Clean Code

This commit is contained in:
Timothyxxx
2024-03-27 16:24:36 +08:00
parent 64178d7ec1
commit 6c8a7af79d
67 changed files with 0 additions and 4928 deletions

172
annotation/.gitignore vendored
View File

@@ -1,172 +0,0 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# experiments
experiments/**/*.png
experiments/**/*.csv
experiments/**/*.mp4
experiments/**/*.jsonl
experiments/**/*.json
experiments/**/*.md
experiments/**/*.txt
# macos
*DS_Store*

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 DuckAI
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,50 +0,0 @@
# OBS Setup
These are instructions on setting up OBS (Open Broadcaster Software) to record screen activity for creating the multimodal computer dataset.
## Installation
1. Go to the OBS Project website: [https://obsproject.com/](https://obsproject.com/).
2. Choose the appropriate installer for your operating system.
3.
![Operating System Selection](readme_images/Screenshot%202023-06-17%20220155.png)
3. Run the installer from your downloads folder and grant OBS the necessary permissions for installation.
![Installer Run](readme_images/Screenshot%202023-06-24%20115916.png)
4. Keep the default settings and proceed through the installation wizard by clicking "Next" and then "Finish."
![Installation Wizard](readme_images/Screenshot%202023-06-24%20120133.png)
5. OBS should now be open. If not, search for and open the application.
![Open OBS](readme_images/Screenshot%202023-06-17%20221407.png)
## Enabling OBS WebSocket Server
1. Click on "Tools" in the Navigation Bar within OBS, and then select "WebSocket Server Settings." A pop-up window will appear.
![WebSocket Server Settings](readme_images/Screenshot%202023-06-17%20221553.png)
2. Check the box next to "Enable WebSocket server" and uncheck the box next to "Enable Authentication." Click "Apply," then "Ok." You should return to the main OBS page.
Make sure the port is set to 4455.
![Enable WebSocket Server](readme_images/Screenshot%202023-06-24%20120347.png)
## Adding Display Capture and Recording
1. Now, back on the home page of OBS, select "Scene." Under "Sources," click the "+" button and then click "Display Capture." (in MacOS this is MacOS Screen Capture)
![Display Capture](readme_images/Screenshot%202023-06-24%20110823.png)
2. Select "Ok."
![Confirm Display Capture](readme_images/Screenshot%202023-06-24%20111017.png)
3. Make sure the "Display" is set to your main display, and you should see your screen on the canvas. Select "Ok." _(in MacOS if your screen is black with a red square in the top left try to disable then re-enable OBS Screen Recording permissions, this has worked before)_
![Main Display](readme_images/Screenshot%202023-06-24%20112001.png)
4. Now you can close OBS and OBS will opened and controlled automatically when you launch the Computer Tracker App. Also, the Computer Tracker app creates a new OBS profile so you don't have to worry about your previous settings being messed up.
![Recording in Progress](readme_images/Screenshot%202023-06-24%20113548.png)

View File

@@ -1,98 +0,0 @@
# DuckTrack
This is the repository for the DuckAI DuckTrack app which records all keyboard and mouse input as well as the screen for use in a multimodal computer interaction dataset.
## Installation & Setup
### Download Application
<!-- TODO: add prebuilt applications in github releases -->
Download the pre-built application for your system [here](https://github.com/TheDuckAI/DuckTrack/releases/).
Make sure you have OBS downloaded with the following configuration:
1. Have a screen capture source recording your whole main screen.
2. Enable desktop audio and mute microphone.
3. Make sure the default websocket is enabled.
More detailed instructions for OBS setup and installation located [here](OBS_SETUP.md).
If you are on MacOS, make sure to enable to the following Privacy & Security permissions before running the app:
1. Accessibility (for playing back actions)
2. Input Monitoring (for reading keyboard inputs)
Make sure to accept all other security permission dialogues to ensure that the app works properly.
### Build from source
Have Python >=3.11.
Clone this repo and `cd` into it:
```bash
$ git clone https://github.com/TheDuckAI/DuckTrack
$ cd DuckTrack
```
Install the dependencies for this project:
```bash
$ pip install -r requirements.txt
```
Build the application:
```bash
$ python3 build.py
```
The built application should be located in the generated `dist` directory. After this, follow the remaining relevant setup instructions.
## Running the App
You can run the app like any other desktop app on your computer. If you decided to not download the app or build it from source, just run `python main.py` and it should work the same. You will be interacting with the app through an app tray icon or a small window.
### Recording
From the app tray or GUI, you can start and stop a recording as well as pause and resume a recording. Pausing and resuming is important for when you want to hide sensitive information like credit card of login credentials. You can optionally name your recording and give it a description upon stopping a recording. You can also view your recordings by pressing the "Show Recordings" option.
### Playback
You can playback a recording, i.e. simulate the series of events from the recording, by pressing "Play Latest Recording", which plays the latest created recording, or by pressing "Play Custom Recording", which lets you choose a recording to play. You can easily replay the most recently played recording by pressing "Replay Recording".
To stop the app mid-playback, just press `shift`+`esc` on your keyboard.
### Misc
To quit the app, you just press the "Quit" option.
## Recording Format
Recordings are stored in `Documents/DuckTrack_Recordings`. Each recording is a directory containing:
1. `events.jsonl` file - sequence of all computer actions that happened. A sample event may look like this:
```json
{"time_stamp": 1234567.89, "action": "move", "x": 69.0, "y": 420.0}
```
1. `metadata.json` - stores metadata about the computer that made the recording
2. `README.md` - stores the description for the recording
3. MP4 file - the screen recording from OBS of the recording.
Here is a [sample recording](example) for further reference.
## Technical Overview
<!-- maybe put a nice graphical representation of the app here -->
*TDB*
## Known Bugs
- After doing lots of playbacks on macOS, a segfault will occur.
- Mouse movement is not captured when the current application is using raw input, i.e. video games.
- OBS may not open in the background properly on some Linux machines.
## Things To Do
- Add logging
- Testing
- CI (with builds and testing)
- Add way to hide/show window from the app tray (and it saves that as a preference?)
- Make saving preferences a thing generally, like with natural scrolling too

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,27 +0,0 @@
import shutil
import sys
from pathlib import Path
from platform import system
from subprocess import CalledProcessError, run
project_dir = Path(".")
assets_dir = project_dir / "assets"
main_py = project_dir / "main.py"
icon_file = assets_dir / ("duck.ico" if system() == "Windows" else "duck.png")
for dir_to_remove in ["dist", "build"]:
dir_path = project_dir / dir_to_remove
if dir_path.exists():
shutil.rmtree(dir_path)
pyinstaller_cmd = [
"pyinstaller", "--onefile", "--windowed",
f"--add-data={assets_dir}{';' if system() == 'Windows' else ':'}{assets_dir}",
f"--name=DuckTrack", f"--icon={icon_file}", str(main_py)
]
try:
run(pyinstaller_cmd, check=True)
except CalledProcessError as e:
print("An error occurred while running PyInstaller:", e)
sys.exit(1)

View File

@@ -1 +0,0 @@
from .app import MainInterface

View File

@@ -1,251 +0,0 @@
import os
import sys
from platform import system
from PyQt6.QtCore import QTimer, pyqtSlot
from PyQt6.QtGui import QAction, QIcon
from PyQt6.QtWidgets import (QApplication, QCheckBox, QDialog, QFileDialog,
QFormLayout, QLabel, QLineEdit, QMenu,
QMessageBox, QPushButton, QSystemTrayIcon,
QTextEdit, QVBoxLayout, QWidget)
from .obs_client import close_obs, is_obs_running, open_obs
from .playback import Player, get_latest_recording
from .recorder import Recorder
from .util import get_recordings_dir, open_file
class TitleDescriptionDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Recording Details")
layout = QVBoxLayout(self)
self.form_layout = QFormLayout()
self.title_label = QLabel("Title:")
self.title_input = QLineEdit(self)
self.form_layout.addRow(self.title_label, self.title_input)
self.description_label = QLabel("Description:")
self.description_input = QTextEdit(self)
self.form_layout.addRow(self.description_label, self.description_input)
layout.addLayout(self.form_layout)
self.submit_button = QPushButton("Save", self)
self.submit_button.clicked.connect(self.accept)
layout.addWidget(self.submit_button)
def get_values(self):
return self.title_input.text(), self.description_input.toPlainText()
class MainInterface(QWidget):
def __init__(self, app: QApplication):
super().__init__()
self.tray = QSystemTrayIcon(QIcon(resource_path("assets/duck.png")))
self.tray.show()
self.app = app
self.init_tray()
self.init_window()
if not is_obs_running():
self.obs_process = open_obs()
def init_window(self):
self.setWindowTitle("DuckTrack")
layout = QVBoxLayout(self)
self.toggle_record_button = QPushButton("Start Recording", self)
self.toggle_record_button.clicked.connect(self.toggle_record)
layout.addWidget(self.toggle_record_button)
self.toggle_pause_button = QPushButton("Pause Recording", self)
self.toggle_pause_button.clicked.connect(self.toggle_pause)
self.toggle_pause_button.setEnabled(False)
layout.addWidget(self.toggle_pause_button)
self.show_recordings_button = QPushButton("Show Recordings", self)
self.show_recordings_button.clicked.connect(lambda: open_file(get_recordings_dir()))
layout.addWidget(self.show_recordings_button)
self.play_latest_button = QPushButton("Play Latest Recording", self)
self.play_latest_button.clicked.connect(self.play_latest_recording)
layout.addWidget(self.play_latest_button)
self.play_custom_button = QPushButton("Play Custom Recording", self)
self.play_custom_button.clicked.connect(self.play_custom_recording)
layout.addWidget(self.play_custom_button)
self.replay_recording_button = QPushButton("Replay Recording", self)
self.replay_recording_button.clicked.connect(self.replay_recording)
self.replay_recording_button.setEnabled(False)
layout.addWidget(self.replay_recording_button)
self.quit_button = QPushButton("Quit", self)
self.quit_button.clicked.connect(self.quit)
layout.addWidget(self.quit_button)
self.natural_scrolling_checkbox = QCheckBox("Natural Scrolling", self, checked=system() == "Darwin")
layout.addWidget(self.natural_scrolling_checkbox)
self.natural_scrolling_checkbox.stateChanged.connect(self.toggle_natural_scrolling)
self.setLayout(layout)
def init_tray(self):
self.menu = QMenu()
self.tray.setContextMenu(self.menu)
self.toggle_record_action = QAction("Start Recording")
self.toggle_record_action.triggered.connect(self.toggle_record)
self.menu.addAction(self.toggle_record_action)
self.toggle_pause_action = QAction("Pause Recording")
self.toggle_pause_action.triggered.connect(self.toggle_pause)
self.toggle_pause_action.setVisible(False)
self.menu.addAction(self.toggle_pause_action)
self.show_recordings_action = QAction("Show Recordings")
self.show_recordings_action.triggered.connect(lambda: open_file(get_recordings_dir()))
self.menu.addAction(self.show_recordings_action)
self.play_latest_action = QAction("Play Latest Recording")
self.play_latest_action.triggered.connect(self.play_latest_recording)
self.menu.addAction(self.play_latest_action)
self.play_custom_action = QAction("Play Custom Recording")
self.play_custom_action.triggered.connect(self.play_custom_recording)
self.menu.addAction(self.play_custom_action)
self.replay_recording_action = QAction("Replay Recording")
self.replay_recording_action.triggered.connect(self.replay_recording)
self.menu.addAction(self.replay_recording_action)
self.replay_recording_action.setVisible(False)
self.quit_action = QAction("Quit")
self.quit_action.triggered.connect(self.quit)
self.menu.addAction(self.quit_action)
self.menu.addSeparator()
self.natural_scrolling_option = QAction("Natural Scrolling", checkable=True, checked=system() == "Darwin")
self.natural_scrolling_option.triggered.connect(self.toggle_natural_scrolling)
self.menu.addAction(self.natural_scrolling_option)
@pyqtSlot()
def replay_recording(self):
player = Player()
if hasattr(self, "last_played_recording_path"):
player.play(self.last_played_recording_path)
else:
self.display_error_message("No recording has been played yet!")
@pyqtSlot()
def play_latest_recording(self):
player = Player()
recording_path = get_latest_recording()
self.last_played_recording_path = recording_path
self.replay_recording_action.setVisible(True)
self.replay_recording_button.setEnabled(True)
player.play(recording_path)
@pyqtSlot()
def play_custom_recording(self):
player = Player()
directory = QFileDialog.getExistingDirectory(None, "Select Recording", get_recordings_dir())
if directory:
self.last_played_recording_path = directory
self.replay_recording_button.setEnabled(True)
self.replay_recording_action.setVisible(True)
player.play(directory)
@pyqtSlot()
def quit(self):
if hasattr(self, "recorder_thread"):
self.toggle_record()
if hasattr(self, "obs_process"):
close_obs(self.obs_process)
self.app.quit()
def closeEvent(self, event):
self.quit()
@pyqtSlot()
def toggle_natural_scrolling(self):
sender = self.sender()
if sender == self.natural_scrolling_checkbox:
state = self.natural_scrolling_checkbox.isChecked()
self.natural_scrolling_option.setChecked(state)
else:
state = self.natural_scrolling_option.isChecked()
self.natural_scrolling_checkbox.setChecked(state)
@pyqtSlot()
def toggle_pause(self):
if self.recorder_thread._is_paused:
self.recorder_thread.resume_recording()
self.toggle_pause_action.setText("Pause Recording")
self.toggle_pause_button.setText("Pause Recording")
else:
self.recorder_thread.pause_recording()
self.toggle_pause_action.setText("Resume Recording")
self.toggle_pause_button.setText("Resume Recording")
@pyqtSlot()
def toggle_record(self):
if not hasattr(self, "recorder_thread"):
self.recorder_thread = Recorder(natural_scrolling=self.natural_scrolling_checkbox.isChecked())
self.recorder_thread.recording_stopped.connect(self.on_recording_stopped)
self.recorder_thread.start()
self.update_menu(True)
else:
self.recorder_thread.stop_recording()
self.recorder_thread.terminate()
recording_dir = self.recorder_thread.recording_path
del self.recorder_thread
dialog = TitleDescriptionDialog()
QTimer.singleShot(0, dialog.raise_)
result = dialog.exec()
if result == QDialog.DialogCode.Accepted:
title, description = dialog.get_values()
if title:
renamed_dir = os.path.join(os.path.dirname(recording_dir), title)
os.rename(recording_dir, renamed_dir)
with open(os.path.join(renamed_dir, 'README.md'), 'w') as f:
f.write(description)
self.on_recording_stopped()
@pyqtSlot()
def on_recording_stopped(self):
self.update_menu(False)
def update_menu(self, is_recording: bool):
self.toggle_record_button.setText("Stop Recording" if is_recording else "Start Recording")
self.toggle_record_action.setText("Stop Recording" if is_recording else "Start Recording")
self.toggle_pause_button.setEnabled(is_recording)
self.toggle_pause_action.setVisible(is_recording)
def display_error_message(self, message):
QMessageBox.critical(None, "Error", message)
def resource_path(relative_path: str) -> str:
if hasattr(sys, '_MEIPASS'):
base_path = getattr(sys, "_MEIPASS")
else:
base_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
return os.path.join(base_path, relative_path)

View File

@@ -1,33 +0,0 @@
from pynput.keyboard import Listener
from .util import name_to_key
class KeyCombinationListener:
"""
Simple and bad key combination listener.
"""
def __init__(self):
self.current_keys = set()
self.callbacks = {}
self.listener = Listener(on_press=self.on_key_press, on_release=self.on_key_release)
def add_comb(self, keys, callback):
self.callbacks[tuple([name_to_key(key_name) for key_name in sorted(keys)])] = callback
def on_key_press(self, key):
self.current_keys.add(key)
for comb, callback in self.callbacks.items():
if all(k in self.current_keys for k in comb):
return callback()
def on_key_release(self, key):
if key in self.current_keys:
self.current_keys.remove(key)
def start(self):
self.listener.start()
def stop(self):
self.listener.stop()

View File

@@ -1,60 +0,0 @@
import json
import os
import uuid
from datetime import datetime
from platform import uname
from screeninfo import get_monitors
class MetadataManager:
"""
Handles various system metadata collection.
"""
def __init__(self, recording_path: str, natural_scrolling: bool):
self.recording_path = recording_path
self.metadata = uname()._asdict()
self.metadata["id"] = uuid.getnode()
main_monitor = get_monitors()[0]
self.metadata["screen_width"] = main_monitor.width
self.metadata["screen_height"] = main_monitor.height
try:
match self.metadata["system"]:
case "Windows":
import wmi
for item in wmi.WMI().Win32_ComputerSystem():
self.metadata["model"] = item.Model
break
case "Darwin":
import subprocess
model = subprocess.check_output(["sysctl", "-n", "hw.model"]).decode().strip()
self.metadata["model"] = model
case "Linux":
with open("/sys/devices/virtual/dmi/id/product_name", "r") as f:
self.metadata["model"] = f.read().strip()
except:
self.metadata["model"] = "Unknown"
self.metadata["scroll_direction"] = -1 if natural_scrolling else 1
def save_metadata(self):
metadata_path = os.path.join(self.recording_path, "metadata.json")
with open(metadata_path, "w") as f:
json.dump(self.metadata, f, indent=4)
def collect(self):
self.metadata["start_time"] = self._get_time_stamp()
def end_collect(self):
self.metadata["stop_time"] = self._get_time_stamp()
def add_obs_record_state_timings(self, record_state_events: dict[str, float]):
self.metadata["obs_record_state_timings"] = record_state_events
def _get_time_stamp(self):
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

View File

@@ -1,200 +0,0 @@
import os
import subprocess
import time
from platform import system
import obsws_python as obs
import psutil
def is_obs_running() -> bool:
try:
for process in psutil.process_iter(attrs=["pid", "name"]):
if "obs" in process.info["name"].lower():
return True
return False
except:
raise Exception("Could not check if OBS is running already. Please check manually.")
def close_obs(obs_process: subprocess.Popen):
if obs_process:
obs_process.terminate()
try:
obs_process.wait(timeout=5)
except subprocess.TimeoutExpired:
obs_process.kill()
def find_obs() -> str:
common_paths = {
"Windows": [
"C:\\Program Files\\obs-studio\\bin\\64bit\\obs64.exe",
"C:\\Program Files (x86)\\obs-studio\\bin\\32bit\\obs32.exe"
],
"Darwin": [
"/Applications/OBS.app/Contents/MacOS/OBS",
"/opt/homebrew/bin/obs"
],
"Linux": [
"/usr/bin/obs",
"/usr/local/bin/obs"
]
}
for path in common_paths.get(system(), []):
if os.path.exists(path):
return path
try:
if system() == "Windows":
obs_path = subprocess.check_output("where obs", shell=True).decode().strip()
else:
obs_path = subprocess.check_output("which obs", shell=True).decode().strip()
if os.path.exists(obs_path):
return obs_path
except subprocess.CalledProcessError:
pass
return "obs"
def open_obs() -> subprocess.Popen:
try:
obs_path = find_obs()
if system() == "Windows":
# you have to change the working directory first for OBS to find the correct locale on windows
os.chdir(os.path.dirname(obs_path))
obs_path = os.path.basename(obs_path)
return subprocess.Popen([obs_path, "--startreplaybuffer", "--minimize-to-tray"])
except:
raise Exception("Failed to find OBS, please open OBS manually.")
class OBSClient:
"""
Controls the OBS client via the OBS websocket.
Sets all the correct settings for recording.
"""
def __init__(
self,
recording_path: str,
metadata: dict,
fps=30,
output_width=1280,
output_height=720,
):
self.metadata = metadata
self.req_client = obs.ReqClient()
self.event_client = obs.EventClient()
self.record_state_events = {}
def on_record_state_changed(data):
output_state = data.output_state
print("record state changed:", output_state)
if output_state not in self.record_state_events:
self.record_state_events[output_state] = []
self.record_state_events[output_state].append(time.perf_counter())
self.event_client.callback.register(on_record_state_changed)
self.old_profile = self.req_client.get_profile_list().current_profile_name
if "computer_tracker" not in self.req_client.get_profile_list().profiles:
self.req_client.create_profile("computer_tracker")
else:
self.req_client.set_current_profile("computer_tracker")
self.req_client.create_profile("temp")
self.req_client.remove_profile("temp")
self.req_client.set_current_profile("computer_tracker")
base_width = metadata["screen_width"]
base_height = metadata["screen_height"]
if metadata["system"] == "Darwin":
# for retina displays
# TODO: check if external displays are messed up by this
base_width *= 2
base_height *= 2
scaled_width, scaled_height = _scale_resolution(base_width, base_height, output_width, output_height)
self.req_client.set_profile_parameter("Video", "BaseCX", str(base_width))
self.req_client.set_profile_parameter("Video", "BaseCY", str(base_height))
self.req_client.set_profile_parameter("Video", "OutputCX", str(scaled_width))
self.req_client.set_profile_parameter("Video", "OutputCY", str(scaled_height))
self.req_client.set_profile_parameter("Video", "ScaleType", "lanczos")
self.req_client.set_profile_parameter("AdvOut", "RescaleRes", f"{base_width}x{base_height}")
self.req_client.set_profile_parameter("AdvOut", "RecRescaleRes", f"{base_width}x{base_height}")
self.req_client.set_profile_parameter("AdvOut", "FFRescaleRes", f"{base_width}x{base_height}")
self.req_client.set_profile_parameter("Video", "FPSCommon", str(fps))
self.req_client.set_profile_parameter("Video", "FPSInt", str(fps))
self.req_client.set_profile_parameter("Video", "FPSNum", str(fps))
self.req_client.set_profile_parameter("Video", "FPSDen", "1")
self.req_client.set_profile_parameter("SimpleOutput", "RecFormat2", "mp4")
bitrate = int(_get_bitrate_mbps(scaled_width, scaled_height, fps=fps) * 1000 / 50) * 50
self.req_client.set_profile_parameter("SimpleOutput", "VBitrate", str(bitrate))
# do this in order to get pause & resume
self.req_client.set_profile_parameter("SimpleOutput", "RecQuality", "Small")
self.req_client.set_profile_parameter("SimpleOutput", "FilePath", recording_path)
# TODO: not all OBS configs have this, maybe just instruct the user to mute themselves
try:
self.req_client.set_input_mute("Mic/Aux", muted=True)
except obs.error.OBSSDKRequestError :
# In case there is no Mic/Aux input, this will throw an error
pass
def start_recording(self):
self.req_client.start_record()
def stop_recording(self):
self.req_client.stop_record()
self.req_client.set_current_profile(self.old_profile) # restore old profile
def pause_recording(self):
self.req_client.pause_record()
def resume_recording(self):
self.req_client.resume_record()
def _get_bitrate_mbps(width: int, height: int, fps=30) -> float:
"""
Gets the YouTube recommended bitrate in Mbps for a given resolution and framerate.
Refer to https://support.google.com/youtube/answer/1722171?hl=en#zippy=%2Cbitrate
"""
resolutions = {
(7680, 4320): {30: 120, 60: 180},
(3840, 2160): {30: 40, 60: 60.5},
(2160, 1440): {30: 16, 60: 24},
(1920, 1080): {30: 8, 60: 12},
(1280, 720): {30: 5, 60: 7.5},
(640, 480): {30: 2.5, 60: 4},
(480, 360): {30: 1, 60: 1.5}
}
if (width, height) in resolutions:
return resolutions[(width, height)].get(fps)
else:
# approximate the bitrate using a simple linear model
area = width * height
multiplier = 3.5982188179592543e-06 if fps == 30 else 5.396175171097084e-06
constant = 2.418399836285939 if fps == 30 else 3.742780056500365
return multiplier * area + constant
def _scale_resolution(base_width: int, base_height: int, target_width: int, target_height: int) -> tuple[int, int]:
target_area = target_width * target_height
aspect_ratio = base_width / base_height
scaled_height = int((target_area / aspect_ratio) ** 0.5)
scaled_width = int(aspect_ratio * scaled_height)
return scaled_width, scaled_height

View File

@@ -1,188 +0,0 @@
import json
import math
import os
import sys
import time
import pyautogui
from pynput.keyboard import Controller as KeyboardController
from pynput.keyboard import Key
from pynput.mouse import Button
from pynput.mouse import Controller as MouseController
from .keycomb import KeyCombinationListener
from .util import (fix_windows_dpi_scaling, get_recordings_dir, name_to_button,
name_to_key)
pyautogui.PAUSE = 0
pyautogui.DARWIN_CATCH_UP_TIME = 0
class Player:
"""
Plays back recordings.
"""
def __init__(self):
self.stop_playback = False
self.listener = KeyCombinationListener()
def stop_comb_pressed():
self.stop_playback = True
return False
self.listener.add_comb(("shift", "esc"), stop_comb_pressed)
self.listener.start()
def play(self, recording_path: str):
with open(os.path.join(recording_path, "events.jsonl"), "r") as f:
events = [json.loads(line) for line in f.readlines()]
with open(os.path.join(recording_path, "metadata.json"), "r") as f:
metadata = json.load(f)
self.playback(events, metadata)
def playback(self, events: list[dict], metadata: dict):
if metadata["system"] == "Windows":
fix_windows_dpi_scaling()
mouse_controller = MouseController()
keyboard_controller = KeyboardController()
if not events:
self.listener.stop()
return
presses_to_skip = 0
releases_to_skip = 0
in_click_sequence = False
for i, event in enumerate(events):
start_time = time.perf_counter()
if self.stop_playback:
return
def do_mouse_press(button):
for j, second_event in enumerate(events[i+1:]):
# make sure the time between mouse clicks is less than 500ms
if second_event["time_stamp"] - event["time_stamp"] > 0.5:
break
if "x" in second_event and "y" in second_event:
# if the mouse moves out of the click radius/rectangle, it is not a click sequence
if math.sqrt((second_event["y"] - event["y"]) ** 2 +
(second_event["x"] - event["x"]) ** 2) > 4:
break
if second_event["action"] == "click" and second_event["pressed"]:
for k, third_event in enumerate(events[i+j+2:]):
if third_event["time_stamp"] - second_event["time_stamp"] > 0.5:
break
if "x" in third_event and "y" in third_event:
if math.sqrt((third_event["y"] - event["y"]) ** 2 +
(third_event["x"] - event["x"]) ** 2) > 5:
break
if third_event["action"] == "click" and third_event["pressed"]:
mouse_controller.click(button, 3)
return 2, 2
mouse_controller.click(button, 2)
return 1, 1
mouse_controller.press(button)
return 0, 0
if event["action"] == "move":
mouse_controller.position = (event["x"], event["y"])
elif event["action"] == "click":
button = name_to_button(event["button"])
if event["pressed"]:
if presses_to_skip == 0:
presses, releases = do_mouse_press(button)
presses_to_skip += presses
releases_to_skip += releases
if presses > 0:
in_click_sequence = True
else:
presses_to_skip -= 1
else:
if releases_to_skip == 0:
mouse_controller.release(button)
if in_click_sequence:
keyboard_controller.press(Key.shift)
mouse_controller.click(Button.left)
keyboard_controller.release(Key.shift)
in_click_sequence = False
else:
releases_to_skip -= 1
elif event["action"] == "scroll":
if metadata["system"] == "Windows":
# for some reason on windows, pynput scroll is correct but pyautogui is not
mouse_controller.scroll(metadata["scroll_direction"] * event["dx"], metadata["scroll_direction"] * event["dy"])
else:
pyautogui.hscroll(clicks=metadata["scroll_direction"] * event["dx"])
pyautogui.vscroll(clicks=metadata["scroll_direction"] * event["dy"])
elif event["action"] in ["press", "release"]:
key = name_to_key(event["name"])
if event["action"] == "press":
keyboard_controller.press(key)
else:
keyboard_controller.release(key)
# sleep for the correct amount of time
end_time = time.perf_counter()
execution_time = end_time - start_time
if i + 1 < len(events):
desired_delay = events[i + 1]["time_stamp"] - event["time_stamp"]
delay = desired_delay - execution_time
if delay < 0:
print(f"warning: behind by {-delay * 1000:.3f} ms")
elif delay != 0:
wait_until = time.perf_counter() + delay
while time.perf_counter() < wait_until:
pass
self.listener.stop()
def get_latest_recording() -> str:
recordings_dir = get_recordings_dir()
if not os.path.exists(recordings_dir):
raise Exception("The recordings directory does not exist")
recordings = [os.path.join(recordings_dir, f) for f in os.listdir(recordings_dir) if os.path.isdir(os.path.join(recordings_dir, f))]
if len(recordings) == 0:
raise Exception("You have no recordings to play back")
latest_recording = max(recordings, key=os.path.getctime)
return latest_recording
def main():
player = Player()
if len(sys.argv) > 1:
recording_path = sys.argv[1]
else:
recording_path = get_latest_recording()
player.play(recording_path)
if __name__ == "__main__":
n = 3
print("press shift+esc to stop the playback")
print(f"starting in {n} seconds...")
time.sleep(n)
main()

View File

@@ -1,145 +0,0 @@
import json
import os
import time
from datetime import datetime
from platform import system
from queue import Queue
from pynput import keyboard, mouse
from pynput.keyboard import KeyCode
from PyQt6.QtCore import QThread, pyqtSignal
from .metadata import MetadataManager
from .obs_client import OBSClient
from .util import fix_windows_dpi_scaling, get_recordings_dir
class Recorder(QThread):
"""
Makes recordings.
"""
recording_stopped = pyqtSignal()
def __init__(self, natural_scrolling: bool):
super().__init__()
if system() == "Windows":
fix_windows_dpi_scaling()
self.recording_path = self._get_recording_path()
self._is_recording = False
self._is_paused = False
self.event_queue = Queue()
self.events_file = open(os.path.join(self.recording_path, "events.jsonl"), "a")
self.metadata_manager = MetadataManager(
recording_path=self.recording_path,
natural_scrolling=natural_scrolling
)
self.obs_client = OBSClient(recording_path=self.recording_path,
metadata=self.metadata_manager.metadata)
self.mouse_listener = mouse.Listener(
on_move=self.on_move,
on_click=self.on_click,
on_scroll=self.on_scroll)
self.keyboard_listener = keyboard.Listener(
on_press=self.on_press,
on_release=self.on_release)
def on_move(self, x, y):
if not self._is_paused:
self.event_queue.put({"time_stamp": time.perf_counter(),
"action": "move",
"x": x,
"y": y}, block=False)
def on_click(self, x, y, button, pressed):
if not self._is_paused:
self.event_queue.put({"time_stamp": time.perf_counter(),
"action": "click",
"x": x,
"y": y,
"button": button.name,
"pressed": pressed}, block=False)
def on_scroll(self, x, y, dx, dy):
if not self._is_paused:
self.event_queue.put({"time_stamp": time.perf_counter(),
"action": "scroll",
"x": x,
"y": y,
"dx": dx,
"dy": dy}, block=False)
def on_press(self, key):
if not self._is_paused:
self.event_queue.put({"time_stamp": time.perf_counter(),
"action": "press",
"name": key.char if type(key) == KeyCode else key.name}, block=False)
def on_release(self, key):
if not self._is_paused:
self.event_queue.put({"time_stamp": time.perf_counter(),
"action": "release",
"name": key.char if type(key) == KeyCode else key.name}, block=False)
def run(self):
self._is_recording = True
self.metadata_manager.collect()
self.obs_client.start_recording()
self.mouse_listener.start()
self.keyboard_listener.start()
while self._is_recording:
event = self.event_queue.get()
self.events_file.write(json.dumps(event) + "\n")
def stop_recording(self):
if self._is_recording:
self._is_recording = False
self.metadata_manager.end_collect()
self.mouse_listener.stop()
self.keyboard_listener.stop()
self.obs_client.stop_recording()
self.metadata_manager.add_obs_record_state_timings(self.obs_client.record_state_events)
self.events_file.close()
self.metadata_manager.save_metadata()
self.recording_stopped.emit()
def pause_recording(self):
if not self._is_paused and self._is_recording:
self._is_paused = True
self.obs_client.pause_recording()
self.event_queue.put({"time_stamp": time.perf_counter(),
"action": "pause"}, block=False)
def resume_recording(self):
if self._is_paused and self._is_recording:
self._is_paused = False
self.obs_client.resume_recording()
self.event_queue.put({"time_stamp": time.perf_counter(),
"action": "resume"}, block=False)
def _get_recording_path(self) -> str:
recordings_dir = get_recordings_dir()
if not os.path.exists(recordings_dir):
os.mkdir(recordings_dir)
current_time = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
recording_path = os.path.join(recordings_dir, f"recording-{current_time}")
os.mkdir(recording_path)
return recording_path

View File

@@ -1,38 +0,0 @@
import os
import platform
import subprocess
from pathlib import Path
from pynput.keyboard import Key, KeyCode
from pynput.mouse import Button
def name_to_key(name: str) -> Key | KeyCode:
try:
return getattr(Key, name)
except AttributeError:
return KeyCode.from_char(name)
def name_to_button(name: str) -> Button:
return getattr(Button, name)
def get_recordings_dir() -> str:
documents_folder = Path.home() / 'Documents' / 'DuckTrack_Recordings'
return str(documents_folder)
def fix_windows_dpi_scaling():
"""
Fixes DPI scaling issues with legacy windows applications
Reference: https://pynput.readthedocs.io/en/latest/mouse.html#ensuring-consistent-coordinates-between-listener-and-controller-on-windows
"""
import ctypes
PROCESS_PER_MONITOR_DPI_AWARE = 2
ctypes.windll.shcore.SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)
def open_file(path):
if platform.system() == "Windows":
os.startfile(path)
elif platform.system() == "Darwin":
subprocess.Popen(["open", path])
else:
subprocess.Popen(["xdg-open", path])

View File

@@ -1,48 +0,0 @@
import glob
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from scipy.stats import sem, t
def calculate_confidence_interval(data, confidence=0.95):
n = len(data)
m = np.mean(data)
std_err = sem(data)
h = std_err * t.ppf((1 + confidence) / 2, n - 1)
return m, m-h, m+h
runs = glob.glob("run*.txt")
TOTAL_EVENTS = 22509
percent_delays = []
all_delays = []
for run in runs:
with open(run, "r") as f:
delays = [float(line.split()[3]) for line in f if float(line.split()[3]) > 0] # consider only positive delays
percent_delays.append((len(delays) / TOTAL_EVENTS) * 100)
all_delays.extend(delays)
average_percent_delays = np.mean(percent_delays)
confidence_interval_percent_delays = calculate_confidence_interval(percent_delays)
print(f"Average percentage of delayed events across all runs: {average_percent_delays:.2f}%")
print(f"95% Confidence interval: ({confidence_interval_percent_delays[1]:.2f}%, {confidence_interval_percent_delays[2]:.2f}%)")
if all_delays:
mean_delay = np.mean(all_delays)
confidence_interval_delays = calculate_confidence_interval(all_delays)
print(f"Mean delay time: {mean_delay:.2f}")
print(f"95% Confidence interval for delay time: ({confidence_interval_delays[1]:.2f}, {confidence_interval_delays[2]:.2f})")
else:
print("No delay data available for calculation.")
sns.histplot(all_delays, bins=30, kde=False)
plt.xlabel('Delay Time (ms)')
plt.ylabel('Frequency')
plt.yscale('log')
plt.title('Histogram of Delay Times (macOS)')
plt.savefig('delays.png', dpi=300)
plt.show()

View File

@@ -1,110 +0,0 @@
import glob
import os
import cv2
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
from skimage.metrics import structural_similarity as ssim
from tqdm import tqdm
# use this: https://sketch.io
def calculate_rmse(imageA, imageB):
err = np.sum((imageA - imageB) ** 2)
err /= float(imageA.shape[0] * imageA.shape[1])
return np.sqrt(err)
def compare_images(ground_truth_path, sample_paths):
results = []
gt_image = cv2.imread(ground_truth_path, cv2.IMREAD_GRAYSCALE)
if gt_image is None:
raise ValueError("Ground truth image could not be read. Please check the file path.")
gt_image = gt_image.astype("float") / 255.0
for path in tqdm(sample_paths):
sample_image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
if sample_image is None:
print(f"WARNING: Sample image at path {path} could not be read. Skipping this image.")
continue
sample_image = sample_image.astype("float") / 255.0
rmse_value = calculate_rmse(gt_image, sample_image)
ssim_value, _ = ssim(gt_image, sample_image, full=True, data_range=1) # Corrected line
diff_mask = cv2.absdiff(gt_image, sample_image)
# plt.imshow(diff_mask * 255, cmap='gray')
# plt.title(f'Difference Mask for {os.path.basename(path)}\nRMSE: {rmse_value:.5f} - SSIM: {ssim_value:.5f}')
# plt.show()
results.append({
'path': path,
'rmse': rmse_value,
'ssim': ssim_value,
'diff_mask': diff_mask
})
return results
ground_truth = 'ground_truth.png'
sample_images = glob.glob("samples/*.png")
results = compare_images(ground_truth, sample_images)
for res in results:
print(f"Image: {res['path']} - RMSE: {res['rmse']} - SSIM: {res['ssim']}")
def calculate_confidence_interval(data, confidence_level=0.95):
mean = np.mean(data)
sem = stats.sem(data)
df = len(data) - 1
me = sem * stats.t.ppf((1 + confidence_level) / 2, df)
return mean - me, mean + me
rmse_values = [res['rmse'] for res in results]
ssim_values = [res['ssim'] for res in results]
rmse_mean = np.mean(rmse_values)
rmse_median = np.median(rmse_values)
rmse_stdev = np.std(rmse_values, ddof=1)
ssim_mean = np.mean(ssim_values)
ssim_median = np.median(ssim_values)
ssim_stdev = np.std(ssim_values, ddof=1)
rmse_ci = calculate_confidence_interval(rmse_values)
ssim_ci = calculate_confidence_interval(ssim_values)
print(f"\nRMSE - Mean: {rmse_mean}, Median: {rmse_median}, Std Dev: {rmse_stdev}, 95% CI: {rmse_ci}")
print(f"SSIM - Mean: {ssim_mean}, Median: {ssim_median}, Std Dev: {ssim_stdev}, 95% CI: {ssim_ci}")
print(f"RMSE: {rmse_mean} ± {rmse_ci[1] - rmse_mean}")
print(f"SSIM: {ssim_mean} ± {ssim_ci[1] - ssim_mean}")
def save_average_diff_map(results, save_path='average_diff_map.png'):
if not results:
print("No results available to create an average diff map.")
return
avg_diff_map = None
for res in results:
if avg_diff_map is None:
avg_diff_map = np.zeros_like(res['diff_mask'])
avg_diff_map += res['diff_mask']
avg_diff_map /= len(results)
avg_diff_map = (avg_diff_map * 255).astype(np.uint8)
cv2.imwrite(save_path, avg_diff_map)
# Usage
save_average_diff_map(results)

View File

@@ -1,4 +0,0 @@
success = 10
total = 10
print(success / total)

View File

@@ -1,48 +0,0 @@
import csv
import time
import numpy as np
from tqdm import tqdm
def check_sleep(duration, sleep_function):
start = time.perf_counter()
sleep_function(duration)
end = time.perf_counter()
elapsed = end - start
return abs(elapsed - duration)
def busy_sleep(duration):
end_time = time.perf_counter() + duration
while time.perf_counter() < end_time:
pass
def measure_accuracy(sleep_function, durations, iterations=100):
average_errors = []
for duration in tqdm(durations):
errors = [check_sleep(duration, sleep_function) for _ in range(iterations)]
average_error = np.mean(errors)
average_errors.append(average_error)
return average_errors
durations = np.arange(0.001, 0.101, 0.001) # From 1ms to 100ms in 1ms increments
iterations = 100
sleep_errors = measure_accuracy(time.sleep, durations, iterations)
busy_sleep_errors = measure_accuracy(busy_sleep, durations, iterations)
def save_to_csv(filename, durations, sleep_errors, busy_sleep_errors):
with open(filename, 'w', newline='') as csvfile:
fieldnames = ['duration', 'sleep_error', 'busy_sleep_error']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for duration, sleep_error, busy_sleep_error in zip(durations, sleep_errors, busy_sleep_errors):
writer.writerow({
'duration': duration,
'sleep_error': sleep_error,
'busy_sleep_error': busy_sleep_error
})
print("Data saved to", filename)
save_to_csv('sleep_data.csv', durations * 1000, np.array(sleep_errors) * 1000, np.array(busy_sleep_errors) * 1000)

View File

@@ -1,33 +0,0 @@
import csv
import matplotlib.pyplot as plt
def plot_from_csv(filename, save_plot=False):
durations = []
sleep_errors = []
busy_sleep_errors = []
with open(filename, 'r') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
durations.append(float(row['duration']))
sleep_errors.append(float(row['sleep_error']))
busy_sleep_errors.append(float(row['busy_sleep_error']))
plt.figure(figsize=(10, 5))
plt.plot(durations, sleep_errors, label='time.sleep()', marker='o')
plt.plot(durations, busy_sleep_errors, label='busy_sleep()', marker='x')
plt.xlabel('Desired Delay (ms)')
plt.ylabel('Average Error (ms)')
plt.title('Sleep Accuracy: time.sleep() vs Busy-Wait Loop (macOS)')
plt.legend()
plt.grid(True)
if save_plot:
plt.savefig('sleep_accuracy_plot.png', dpi=300)
print("Plot saved as sleep_accuracy_plot.png")
plt.show()
plot_from_csv('sleep_data.csv', save_plot=True)

View File

@@ -1,110 +0,0 @@
import glob
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.stats as stats
import seaborn as sns
# use this: https://www.estopwatch.net/
def read_file(file_path):
df = pd.read_csv(file_path)
df['Elapsed time'] = pd.to_datetime(df['Elapsed time'], errors='coerce')
return df
def analyze_new_error(run_df, groundtruth_df):
cumulative_errors = run_df['Elapsed time'] - groundtruth_df['Elapsed time']
cumulative_errors_in_seconds = cumulative_errors.dt.total_seconds()
new_errors_in_seconds = cumulative_errors_in_seconds.diff().fillna(cumulative_errors_in_seconds[0])
new_error_points = new_errors_in_seconds[new_errors_in_seconds != 0].index.tolist()
return new_errors_in_seconds[new_error_points]
def calculate_statistics(errors):
if len(errors) == 0:
return {
'mean_error': 0,
'median_error': 0,
'stddev_error': 0,
'rmse_error': 0,
'confidence_interval': (0, 0),
'error_frequency': 0
}
mean_error = np.mean(errors)
median_error = np.median(errors)
stddev_error = np.std(errors)
rmse_error = np.sqrt(np.mean(np.square(errors)))
ci_low, ci_high = stats.t.interval(
confidence=0.95,
df=len(errors) - 1,
loc=mean_error,
scale=stats.sem(errors) if len(errors) > 1 else 0
)
return {
'mean_error': mean_error,
'median_error': median_error,
'stddev_error': stddev_error,
'rmse_error': rmse_error,
'confidence_interval': (ci_low, ci_high),
}
def main():
groundtruth_file = 'groundtruth.csv'
run_files = glob.glob('runs/*.csv')
groundtruth_df = read_file(groundtruth_file)
run_dfs = {f'run{i+1}': read_file(file) for i, file in enumerate(run_files)}
total_errors = []
total_points = 0
all_errors = []
for run, df in run_dfs.items():
errors = analyze_new_error(df, groundtruth_df)
total_errors.extend(errors)
all_errors.extend(errors)
total_points += len(df)
results = calculate_statistics(errors)
error_frequency = len(errors) / len(df)
print(f"Results for {run}:")
print(f"Mean New Error: {results['mean_error']:.5f} seconds")
print(f"Median New Error: {results['median_error']:.5f} seconds")
print(f"Standard Deviation of New Error: {results['stddev_error']:.5f} seconds")
print(f"RMSE of New Error: {results['rmse_error']:.5f} seconds")
print(f"95% Confidence Interval of New Error: ({results['confidence_interval'][0]:.5f}, {results['confidence_interval'][1]:.5f}) seconds")
print(f"New Error Frequency: {error_frequency*100:.5f} %")
print('-----------------------------------------')
total_results = calculate_statistics(total_errors)
total_error_frequency = len(total_errors) / total_points
print("Total Statistics:")
print(f"Mean New Error: {total_results['mean_error']:.5f} seconds")
print(f"Median New Error: {total_results['median_error']:.5f} seconds")
print(f"Standard Deviation of New Error: {total_results['stddev_error']:.5f} seconds")
print(f"RMSE of New Error: {total_results['rmse_error']:.5f} seconds")
print(f"95% Confidence Interval of New Error: ({total_results['confidence_interval'][0]:.5f}, {total_results['confidence_interval'][1]:.5f}) seconds")
print(f"New Error Frequency: {total_error_frequency*100:.5f} %")
# do plus minus
print(f"New Error: {total_results['mean_error']:.5f} ± {total_results['confidence_interval'][1] - total_results['mean_error']:.5f} seconds")
plt.figure(figsize=(10, 5))
sns.histplot(all_errors, bins=12, kde=False)
plt.title('Distribution of Newly Introduced Errors (macOS)')
plt.xlabel('Error Duration (seconds)')
plt.ylabel('Frequency')
plt.savefig('error_dist', dpi=300)
plt.show()
if __name__ == "__main__":
main()

View File

@@ -1,39 +0,0 @@
import signal
import sys
import traceback
from PyQt6.QtWidgets import QApplication
from ducktrack import MainInterface
def main():
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(False)
signal.signal(signal.SIGINT, signal.SIG_DFL)
interface = MainInterface(app)
interface.show()
# TODO: come up with a better error solution to this
original_excepthook = sys.excepthook
def handle_exception(exc_type, exc_value, exc_traceback):
print("Exception type:", exc_type)
print("Exception value:", exc_value)
trace_details = traceback.format_exception(exc_type, exc_value, exc_traceback)
trace_string = "".join(trace_details)
print("Exception traceback:", trace_string)
message = f"An error occurred!\n\n{exc_value}\n\n{trace_string}"
interface.display_error_message(message)
original_excepthook(exc_type, exc_value, exc_traceback)
sys.excepthook = handle_exception
sys.exit(app.exec())
if __name__ == "__main__":
main()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 836 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,9 +0,0 @@
git+https://github.com/moses-palmer/pynput.git@refs/pull/541/head # to make sure that it works on Apple Silicon
pyautogui
obsws-python
PyQt6
Pillow
screeninfo
wmi
psutil
pyinstaller

View File

@@ -1,3 +0,0 @@
# Resource Collection
Manually gain some insights, then scale with careful code.

View File

@@ -1,28 +0,0 @@
import praw
def search_reddit(keyword, subreddit, client_id, client_secret, user_agent, limit=10000):
# Initialize PRAW with your Reddit application credentials
reddit = praw.Reddit(client_id=client_id,
client_secret=client_secret,
user_agent=user_agent)
# Search the specified subreddit for the keyword
results = reddit.subreddit(subreddit).search(keyword, limit=limit)
for post in results:
print(f"Title: {post.title}")
print(f"URL: {post.url}")
print(f"Score: {post.score}")
print(f"Comments: {post.num_comments}")
print("------------------------")
# Example usage
if __name__ == "__main__":
CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
USER_AGENT = 'my_reddit_scraper'
keyword = "how to"
subreddit = "vscode"
search_reddit(keyword, subreddit, CLIENT_ID, CLIENT_SECRET, USER_AGENT)

File diff suppressed because it is too large Load Diff

View File

@@ -1,268 +0,0 @@
id,Source,InvolvedApp
94d95f96-9699-4208-98ba-3c3119edf9c2,https://help.ubuntu.com/lts/ubuntu-help/addremove-install.html.en,OS
bedcedc4-4d72-425e-ad62-21960b11fe0d,https://www.youtube.com/watch?v=D4WyNjt_hbQ&t=2s,OS
43c2d64c-bab5-4dcb-a30c-b888321c319a,https://ubuntu.com/tutorials/command-line-for-beginners#4-creating-folders-and-files,OS
7688b85f-87a4-4e4a-b2f8-f3d6c3f29b82,https://ubuntu.com/tutorials/command-line-for-beginners#5-moving-and-manipulating-files,OS
ec4e3f68-9ea4-4c18-a5c9-69f89d1178b3,https://www.youtube.com/watch?v=D4WyNjt_hbQ&t=2s,OS
a462a795-fdc7-4b23-b689-e8b6df786b78,https://help.ubuntu.com/lts/ubuntu-help/shell-exit.html.en,OS
f9be0997-4b7c-45c5-b05c-4612b44a6118,https://help.ubuntu.com/lts/ubuntu-help/shell-notifications.html.en,OS
ae039631-2b12-4637-84f6-c67d51511be3,https://help.ubuntu.com/lts/ubuntu-help/net-default-browser.html.en,OS
e2eb4bf1-aa93-4192-b55d-03e2fb6dfd15,https://help.ubuntu.com/lts/ubuntu-help/contacts-add-remove.html.en,OS
28cc3b7e-b194-4bc9-8353-d04c0f4d56d2,https://help.ubuntu.com/lts/ubuntu-help/sound-volume.html.en,OS
5ea617a3-0e86-4ba6-aab2-dac9aa2e8d57,https://help.ubuntu.com/lts/ubuntu-help/files-recover.html.en,OS
e0df059f-28a6-4169-924f-b9623e7184cc,https://help.ubuntu.com/lts/ubuntu-help/files-rename.html.en,OS
ddc75b62-7311-4af8-bfb3-859558542b36,https://help.ubuntu.com/lts/ubuntu-help/addremove-remove.html.en,OS
5c433d22-ed9a-4e31-91f5-54cf3e8acd63,https://help.ubuntu.com/lts/ubuntu-help/session-language.html.zh-CN,OS
b6781586-6346-41cd-935a-a6b1487918fc,https://help.ubuntu.com/lts/ubuntu-help/clock-timezone.html.en,OS
b3d4a89c-53f2-4d6b-8b6a-541fb5d205fa,https://help.ubuntu.com/lts/ubuntu-help/bluetooth-turn-on-off.html.en,OS
3ce045a0-877b-42aa-8d2c-b4a863336ab8,https://help.ubuntu.com/lts/ubuntu-help/a11y-font-size.html.en,OS
fe41f596-a71b-4c2f-9b2f-9dcd40b568c3,https://help.ubuntu.com/lts/ubuntu-help/power-percentage.html.en,OS
a4d98375-215b-4a4d-aee9-3d4370fccc41,https://help.ubuntu.com/lts/ubuntu-help/privacy-screen-lock.html.en,OS
765d2b74-88a7-4d50-bf51-34e4106fd24a,https://help.ubuntu.com/lts/ubuntu-help/files-delete.html.en,OS
cc9d4f34-1ca0-4a1b-8ff2-09302696acb9,https://superuser.com/questions/178587/how-do-i-detach-a-process-from-terminal-entirely,OS
5812b315-e7bd-4265-b51f-863c02174c28,https://superuser.com/questions/149404/create-an-ssh-user-who-only-has-permission-to-access-specific-folders,OS
c56de254-a3ec-414e-81a6-83d2ce8c41fa,https://superuser.com/questions/28426/how-to-extract-text-with-ocr-from-a-pdf-on-linux,OS
6ebbfb01-ea72-4226-a2a6-dc428e111ed2,https://superuser.com/questions/46748/how-do-i-make-bash-my-default-shell-on-ubuntu,OS
4d2b519e-e872-4100-8ea3-fe71ab0f9133,https://stackoverflow.com/questions/11530090/adding-a-new-entry-to-the-path-variable-in-zsh,OS
c288e301-e626-4b98-a1ab-159dcb162af5,https://stackoverflow.com/questions/41986507/unable-to-set-default-python-version-to-python3-in-ubuntu,OS
13584542-872b-42d8-b299-866967b5c3ef,https://superuser.com/questions/72176/linux-set-default-terminal-size-and-screen-position,OS
23393935-50c7-4a86-aeea-2b78fd089c5c,https://superuser.com/questions/91307/copying-only-jpg-from-a-directory-structure-to-another-location-linux,OS
f10b16e1-c160-4cb3-989f-7b2ec89bc073,https://www.wikihow.com/Install-Gnome-on-Ubuntu,OS
eb03d19a-b88d-4de4-8a64-ca0ac66f426b,https://www.youtube.com/shorts/t9JLUaT55UQ,MS Excel
0bf05a7d-b28b-44d2-955a-50b41e24012a,https://www.youtube.com/shorts/FPAQaDTS8VY,MS Excel
7b802dad-6e0f-4204-9815-d4e3f57627d8,https://www.youtube.com/shorts/Of-lzeP1usE,MS Excel
7a4e4bc8-922c-4c84-865c-25ba34136be1,https://www.youtube.com/shorts/bvUhr1AHs44,MS Excel
2bd59342-0664-4ccb-ba87-79379096cc08,https://www.youtube.com/shorts/L3Z-F1QTQFY,MS Excel
a9f325aa-8c05-4e4f-8341-9e4358565f4f,https://www.youtube.com/shorts/A0gmEBRKXWs,MS Excel
ecb0df7a-4e8d-4a03-b162-053391d3afaf,https://www.youtube.com/shorts/tXOovKn0H68,MS Excel
7efeb4b1-3d19-4762-b163-63328d66303b,https://www.youtube.com/shorts/4jzXfZNhfmk,MS Excel
4e6fcf72-daf3-439f-a232-c434ce416af6,https://www.youtube.com/shorts/0uxJccNCKcE,MS Excel
6054afcb-5bab-4702-90a0-b259b5d3217c,https://www.youtube.com/shorts/JTbZ8sRxkdU,MS Excel
abed40dc-063f-4598-8ba5-9fe749c0615d,https://www.youtube.com/shorts/xgf4ZpsEx5M,MS Excel
01b269ae-2111-4a07-81fd-3fcd711993b0,https://www.youtube.com/shorts/VrUzPTIwQ04,MS Excel
8b1ce5f2-59d2-4dcc-b0b0-666a714b9a14,https://www.youtube.com/shorts/Hbcwu6IQ1ns,MS Excel
af2b02f7-acee-4be4-8b66-499fab394915,https://www.youtube.com/shorts/AwKsb5VmtBI,MS Excel
da1d63b8-fa12-417b-ba18-f748e5f770f3,https://www.youtube.com/shorts/hquscnbz2-U,MS Excel
636380ea-d5f6-4474-b6ca-b2ed578a20f1,https://www.youtube.com/shorts/_BYL6VOHLGw,"MS Excel, Edge"
5ba77536-05c5-4aae-a9ff-6e298d094c3e,https://www.youtube.com/shorts/CuBC1evUS5I,MS Excel
4bc4eaf4-ca5e-4db2-8138-8d4e65af7c0b,https://www.youtube.com/shorts/1adQWfjN-tI,MS Excel
672a1b02-c62f-4ae2-acf0-37f5fb3052b0,https://www.youtube.com/shorts/2rhdQXI4Lng,MS Excel
648fe544-16ba-44af-a587-12ccbe280ea6,https://www.youtube.com/shorts/sOPBMWaC6Uc,MS Excel
8985d1e4-5b99-4711-add4-88949ebb2308,https://www.youtube.com/shorts/J5ts2Acv9Pc,MS Excel
9e606842-2e27-43bf-b1d1-b43289c9589b,https://www.youtube.com/shorts/B-mGYDFOyUs,MS Excel
fcb6e45b-25c4-4087-9483-03d714f473a9,https://www.youtube.com/shorts/GZipp7nOZS0,MS Excel
68c0c5b7-96f3-4e87-92a7-6c1b967fd2d2,https://www.youtube.com/shorts/JEH5TsK-cCk,"MS Excel, Edge"
fff629ea-046e-4793-8eec-1a5a15c3eb35,https://www.youtube.com/shorts/8WybtCdUT6w,MS Excel
5c9a206c-bb00-4fb6-bb46-ee675c187df5,https://www.youtube.com/shorts/VbQtMNnq9i4,MS Excel
e975ae74-79bd-4672-8d1c-dc841a85781d,https://www.youtube.com/shorts/GjT7gGe5Sr8,MS Excel
34a6938a-58da-4897-8639-9b90d6db5391,https://www.youtube.com/shorts/gW37x2TkzOY,MS Excel
b5a22759-b4eb-4bf2-aeed-ad14e8615f19,https://www.youtube.com/shorts/3xLa-D0C7Ic,MS Excel
2f9913a1-51ed-4db6-bfe0-7e1c95b3139e,https://www.youtube.com/shorts/dGLRcmfVO6Q,MS Excel
2558031e-401d-4579-8e00-3ecf540fb492,https://www.mrexcel.com/board/threads/sales-for-the-first-6-weeks.1249213/,MS Excel
39aa4e37-dc91-482e-99af-132a612d40f3,https://www.libreofficehelp.com/add-insert-delete-copy-move-rename-a-worksheet-in-libreoffice-calc/,LibreOffice Calc
0cecd4f3-74de-457b-ba94-29ad6b5dafb6,https://www.libreofficehelp.com/add-insert-delete-copy-move-rename-a-worksheet-in-libreoffice-calc/,LibreOffice Calc
4188d3a4-077d-46b7-9c86-23e1a036f6c1,https://www.libreofficehelp.com/freeze-unfreeze-rows-columns-ranges-calc/,LibreOffice Calc
51b11269-2ca8-4b2a-9163-f21758420e78,https://www.reddit.com/r/LibreOfficeCalc/comments/186pcc6/how_to_arrange_numbers_in_a_column_from_minimum/,LibreOffice Calc
7e429b8d-a3f0-4ed0-9b58-08957d00b127,https://medium.com/@divyangichaudhari17/how-to-use-vlookup-and-hlookup-in-libre-calc-3370698bb3ff,LibreOffice Calc
f5a90742-3fa2-40fc-a564-f29b054e0337,https://superuser.com/questions/1236149/libreoffice-calc-how-to-apply-functions-to-columns,LibreOffice Calc
22df9241-f8d7-4509-b7f1-37e501a823f7,https://superuser.com/questions/1767185/how-do-you-move-cells-in-libreoffice-calc,LibreOffice Calc
1434ca3e-f9e3-4db8-9ca7-b4c653be7d17,https://www.wikihow.com/Remove-Duplicates-in-Open-Office-Calc,LibreOffice Calc
347ef137-7eeb-4c80-a3bb-0951f26a8aff,https://www.youtube.com/watch?v=bgO40-CjYNY,LibreOffice Calc
6e99a1ad-07d2-4b66-a1ce-ece6d99c20a5,https://www.youtube.com/watch?v=nl-nXjJurhQ,LibreOffice Calc
3aaa4e37-dc91-482e-99af-132a612d40f3,https://www.quora.com/How-can-you-import-export-CSV-files-with-LibreOffice-Calc-or-OpenOffice,LibreOffice Calc
0decd4f3-74de-457b-ba94-29ad6b5dafb6,https://justclickhere.co.uk/resources/checkboxes-tick-boxes-libreoffice-calc/,LibreOffice Calc
37608790-6147-45d0-9f20-1137bb35703d,https://www.youtube.com/shorts/uzPo_CPCHH8,MS Excel
f9584479-3d0d-4c79-affa-9ad7afdd8850,https://youtube.com/shorts/feldd-Pn48c?si=9xJiem2uAHm6Jshb,LibreOffice Calc
d681960f-7bc3-4286-9913-a8812ba3261a,https://www.youtube.com/shorts/d7U1S_IsTVM,LibreOffice Calc
f6a90742-3fa2-40fc-a564-f29b054e0337,https://www.excel-easy.com/examples/drop-down-list.html,LibreOffice Calc
21df9241-f8d7-4509-b7f1-37e501a823f7,https://www.youtube.com/watch?v=p5C4V_AO1UU,LibreOffice Calc
1334ca3e-f9e3-4db8-9ca7-b4c653be7d17,https://techcommunity.microsoft.com/t5/excel/excel-workbook-top-way-too-big-can-t-see-rows-and-columns/m-p/4014694,LibreOffice Calc
357ef137-7eeb-4c80-a3bb-0951f26a8aff,https://www.reddit.com/r/excel/comments/17zny8u/calculating_total_amount_earned_from_total_hours/,LibreOffice Calc
6f99a1ad-07d2-4b66-a1ce-ece6d99c20a5,https://techcommunity.microsoft.com/t5/excel/sumarize-the-sheetnames/m-p/4014716,LibreOffice Calc
aa3a8974-2e85-438b-b29e-a64df44deb4b,https://www.quora.com/Libre-Office-Calc-How-do-I-resize-all-cells-in-a-sheet-to-make-them-fit-to-1-page-for-printing-and-exporting-as-PDF,LibreOffice Calc
a01fbce3-2793-461f-ab86-43680ccbae25,https://superuser.com/questions/1250677/how-to-set-decimal-separator-in-libre-office-calc,LibreOffice Calc
4f07fbe9-70de-4927-a4d5-bb28bc12c52c,https://superuser.com/questions/1081048/libreoffice-calc-how-to-pad-number-to-fixed-decimals-when-used-within-formula,LibreOffice Calc
e3b1d5fa-ed00-4129-bda1-1452bd2b6772,https://www.reddit.com/r/libreoffice/comments/tel112/calc_how_to_calculate_sum_by_categories/,LibreOffice Calc
ca6a9524-f8e9-4d2f-9364-ab0cad567739,https://www.reddit.com/r/libreoffice/comments/113gmyc/how_to_remove_certain_text_from_cells_in_calc/,LibreOffice Calc
a455e8d0-930f-40d2-9575-5e8d2d222f58,https://superuser.com/questions/562944/quickly-fill-blank-cells-in-a-list-in-libreoffice-calc,LibreOffice Calc
83ee22c6-7737-49ce-9b5a-138c3e92af04,https://superuser.com/questions/661102/currency-conversion-in-libreoffice-calc,LibreOffice Calc
819f61c2-ec77-4d3f-9996-0838ae5aacc8,https://superuser.com/questions/381696/creating-a-column-of-working-days-in-libreoffice-calc,LibreOffice Calc
69d577b3-004e-4bca-89b2-0d7c2f6049e3,https://superuser.com/questions/387106/libreoffice-calc-how-to-get-total-for-hhmmss-cells,LibreOffice Calc
0a1bf4ca-d4ea-4618-baa5-6e8dc1b46d82,https://superuser.com/questions/571915/sum-up-to-n-highest-value-out-of-a-series,LibreOffice Calc
ac9bb6cb-1888-43ab-81e4-a98a547918cd,https://superuser.com/questions/1674211/how-to-change-colour-of-slide-number-in-libre-office,LibreOffice Impress
5d901039-a89c-4bfb-967b-bf66f4df075e,https://superuser.com/questions/986776/how-can-i-stretch-an-image-in-a-libreoffice-impress-presentation-to-fill-the-pag,LibreOffice Impress
071d4ace-091a-4ec3-886e-f4be55ae375d,https://superuser.com/questions/706860/hide-slide-numbers-and-slide-footer-on-first-and-second-slide-in-libreoffice-imp?rq=1,LibreOffice Impress
550ce7e7-747b-495f-b122-acdc4d0b8e54,"https://technical-tips.com/blog/software/text-in-libreoffice-strikethrough--6948#:~:text=To%20strikethrough%20Text%20in%20LibreOffice%201%20In%20your,effect%22%20can%20your%20additionally%2C%20for%20example%2C%20double%20underline.",LibreOffice Impress
455d3c66-7dc6-4537-a39a-36d3e9119df7,"https://www.libreofficehelp.com/export-libreoffice-impress-slides-images/#:~:text=Exporting%20a%20single%20slide%20as.jpg%2C.png%2C%20etc%20image%20is,on%20the%20checkbox%20Selection.%20Provide%20jpg%20quality%20options.",LibreOffice Impress
af23762e-2bfd-4a1d-aada-20fa8de9ce07,https://superuser.com/questions/1059080/how-to-make-a-summary-slide-in-impress-listing-the-titles-of-all-slides-autom,LibreOffice Impress
c59742c0-4323-4b9d-8a02-723c251deaa0,https://www.reddit.com/r/libreoffice/comments/17lcdrp/audio_not_supported_in_libreoffice_impress/,LibreOffice Impress
39478d4a-1049-456f-aa77-407811393add,https://www.reddit.com/r/libreoffice/comments/jul3o8/putting_cap_or_hat_or_carat_symbol_in_libre/,LibreOffice Impress
c3ad4442-499f-4e58-bc4e-1a1417ea9b8c,http://maharajacollege.ac.in/material/Libreofficeimpresspdf.pdf,LibreOffice Impress
ef9d12bd-bcee-4ba0-a40e-918400f43ddf,https://www.reddit.com/r/libreoffice/comments/18elh3y/i_closed_the_slide_pannel_on_the_left_and_idk_how/,LibreOffice Impress
9ec204e4-f0a3-42f8-8458-b772a6797cab,https://www.tiktok.com/@lil.d1rt_/video/7247574148887629083,LibreOffice Impress
0f84bef9-9790-432e-92b7-eece357603fb,https://stackoverflow.com/questions/29036788/how-to-disable-libreoffice-impress-to-use-multiple-display,LibreOffice Impress
ce88f674-ab7a-43da-9201-468d38539e4a,https://justclickhere.co.uk/resources/change-slides-in-impress-to-portrait/,LibreOffice Impress
f0a334af-f91b-4c03-b578-aac9bec2b543,https://www.libreofficehelp.com/insert-video-impress-presentation/#Inserting_a_Video_in_Impress,LibreOffice Impress
3b27600c-3668-4abd-8f84-7bcdebbccbdb,https://www.libreofficehelp.com/change-slide-background-impress/#All_Slides,LibreOffice Impress
a097acff-6266-4291-9fbd-137af7ecd439,https://www.youtube.com/watch?v=DDmEvjs4iBw,LibreOffice Impress
21760ecb-8f62-40d2-8d85-0cee5725cb72,https://www.libreofficehelp.com/add-animations-transitions-libreoffice-impress-slides/,LibreOffice Impress
3cc4f35d-fa2e-4555-afb9-741b7c062a74,https://documentation.libreoffice.org/assets/Uploads/Documentation/en/IG7.6/IG76-ImpressGuide.pdf,LibreOffice Impress
6ada715d-3aae-4a32-a6a7-429b2e43fb93,https://www.quora.com/How-do-you-insert-images-into-a-LibreOffice-Writer-document,LibreOffice Writer
ecc2413d-8a48-416e-a3a2-d30106ca36cb,https://www.quora.com/How-can-I-insert-a-blank-page-on-libreoffice,LibreOffice Writer
0e47de2a-32e0-456c-a366-8c607ef7a9d2,https://ask.libreoffice.org/t/how-to-start-page-numbering-on-a-certain-page/39931/4,LibreOffice Writer
4bcb1253-a636-4df4-8cb0-a35c04dfef31,https://www.libreofficehelp.com/save-export-writer-documents-in-pdf-epub-format/,LibreOffice Writer
0810415c-bde4-4443-9047-d5f70165a697,https://www.youtube.com/watch?v=Q_AaL6ljudU,LibreOffice Writer
e528b65e-1107-4b8c-8988-490e4fece599,https://www.youtube.com/watch?v=l25Evu4ohKg,LibreOffice Writer
66399b0d-8fda-4618-95c4-bfc6191617e9,https://www.youtube.com/watch?v=l25Evu4ohKg,LibreOffice Writer
936321ce-5236-426a-9a20-e0e3c5dc536f,https://www.youtube.com/watch?v=l25Evu4ohKg,LibreOffice Writer
663876c7-3471-43db-ba51-f410b13d9d7d,https://askubuntu.com/questions/319593/how-to-type-science-equations-in-libre-office,LibreOffice Writer
3ef2b351-8a84-4ff2-8724-d86eae9b842e,https://askubuntu.com/questions/1066351/how-do-you-center-align-in-libreoffice#:~:text=Ctrl%20%2B%20e%20will%20Center%20align%20the%20cursor%20for%20you.,LibreOffice Writer
45d61a06-6545-4422-97b7-bc76cfa964c1,https://stackoverflow.com/questions/71685737/how-to-replace-all-newlines-with-paragraph-marks-in-libreoffice-write,LibreOffice Writer
0b17a146-2934-46c7-8727-73ff6b6483e8,https://askubuntu.com/questions/245695/how-do-you-insert-subscripts-and-superscripts-into-ordinary-non-formula-text-i,LibreOffice Writer
0e763496-b6bb-4508-a427-fad0b6c3e195,https://ask.libreoffice.org/t/how-do-i-change-the-font-for-the-whole-document-in-writer/9220,LibreOffice Writer
f178a4a9-d090-4b56-bc4c-4b72a61a035d,https://ask.libreoffice.org/t/how-do-i-make-times-new-roman-the-default-font-in-lo/64604,LibreOffice Writer
0a0faba3-5580-44df-965d-f562a99b291c,https://stackoverflow.com/questions/64528055/how-to-make-part-of-my-sentence-left-aligned-and-rest-as-right-aligned,LibreOffice Writer
e246f6d8-78d7-44ac-b668-fcf47946cb50,https://ask.libreoffice.org/t/how-to-change-text-size-color-of-italic-font/77712,LibreOffice Writer
8472fece-c7dd-4241-8d65-9b3cd1a0b568,https://stackoverflow.com/questions/37259827/libreoffice-writer-how-to-set-different-colors-to-each-letter,LibreOffice Writer
88fe4b2d-3040-4c70-9a70-546a47764b48,https://stackoverflow.com/questions/56554555/libreoffice-writer-how-to-create-empty-line-space-after-every-period-in-a-par,LibreOffice Writer
6a33f9b9-0a56-4844-9c3f-96ec3ffb3ba2,https://superuser.com/questions/762500/how-do-i-find-all-highlighted-text-in-libreoffice-writer,LibreOffice Writer
d53ff5ee-3b1a-431e-b2be-30ed2673079b,https://ask.libreoffice.org/t/how-to-convert-all-uppercase-to-lowercase/53341,LibreOffice Writer
72b810ef-4156-4d09-8f08-a0cf57e7cefe,https://superuser.com/questions/657792/libreoffice-writer-how-to-apply-strikethrough-text-formatting?rq=1,LibreOffice Writer
6f81754e-285d-4ce0-b59e-af7edb02d108,https://superuser.com/questions/789473/remove-duplicate-lines-in-libreoffice-openoffice-writer,LibreOffice Writer
41c621f7-3544-49e1-af8d-dafd0f834f75,https://superuser.com/questions/1668018/how-to-auto-format-lines-in-libre-office-writer,LibreOffice Writer
b21acd93-60fd-4127-8a43-2f5178f4a830,https://superuser.com/questions/1097199/how-can-i-double-space-a-document-in-libreoffice?rq=1,LibreOffice Writer
59f21cfb-0120-4326-b255-a5b827b38967,https://docs.videolan.me/vlc-user/desktop/3.0/en/basic/media.html#playing-a-file,VLC player
8ba5ae7a-5ae5-4eab-9fcc-5dd4fe3abf89,https://docs.videolan.me/vlc-user/desktop/3.0/en/basic/recording/playing.html#choose-your-recordings-folder,VLC player
8f080098-ddb1-424c-b438-4e96e5e4786e,https://medium.com/@jetscribe_ai/how-to-extract-mp3-audio-from-videos-using-vlc-media-player-beeef644ebfb,VLC player
bba3381f-b5eb-4439-bd9e-80c22218d5a7,https://www.quora.com/How-do-I-play-online-videos-using-the-VLC-media-player,VLC player
a1c3ab35-02de-4999-a7ed-2fd12c972c6e,https://www.quora.com/How-do-I-compress-a-video-with-VLC,VLC player
fba2c100-79e8-42df-ae74-b592418d54f4,https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s,VLC player
d70666e4-7348-42c7-a06a-664094c5df3c,https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s,VLC player
efcf0d81-0835-4880-b2fd-d866e8bc2294,"https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s, https://help.ubuntu.com/stable/ubuntu-help/look-background.html.en",VLC player
8d9fd4e2-6fdb-46b0-b9b9-02f06495c62f,https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s,VLC player
aa4b5023-aef6-4ed9-bdc9-705f59ab9ad6,https://videoconverter.wondershare.com/vlc/how-to-rotate-a-video-using-vlc.html?gad_source=1&gclid=CjwKCAiA-vOsBhAAEiwAIWR0TaGSOLkYiBeVQGZSyfeUP3g-tIvYxffl5RFIu0-zrUL1IF41eCw1JRoCnCMQAvD_BwE,VLC player
386dbd0e-0241-4a0a-b6a2-6704fba26b1c,https://superuser.com/questions/1708415/pause-and-play-vlc-in-background?rq=1,VLC player
9195653c-f4aa-453d-aa95-787f6ccfaae9,https://superuser.com/questions/1513285/how-can-i-increase-the-maximum-volume-output-by-vlc?rq=1,VLC player
5ac2891a-eacd-4954-b339-98abba077adb,"https://superuser.com/questions/1412810/how-to-prevent-vlc-media-player-from-auto-closing-after-video-end#:%7E:text=Click%20on%20%22Media%22on%20the,VLC%20player%20after%20video%20ending",VLC player
0d95d28a-9587-433b-a805-1fbe5467d598,https://superuser.com/questions/1299036/vlc-how-to-open-the-folder-of-the-current-playing-video?noredirect=1&lq=1,VLC player
d06f0d4d-2cd5-4ede-8de9-598629438c6e,https://superuser.com/questions/1039392/changing-colour-of-vlc-volume-slider,VLC player
a5bbbcd5-b398-4c91-83d4-55e1e31bbb81,https://superuser.com/questions/776056/how-to-hide-bottom-toolbar-in-vlc,VLC player
f3977615-2b45-4ac5-8bba-80c17dbe2a37,https://www.reddit.com/r/Fedora/comments/rhljzd/how_to_run_multiple_instances_of_vlc_media_player/,VLC player
c669a35f-d45a-450e-b1f2-f473748337bb,https://www.quora.com/How-do-I-fast-forward-a-video-in-VLC-player,VLC player
d1ba14d0-fef8-4026-8418-5b581dc68ca0,https://superuser.com/questions/306154/how-to-use-a-b-repeat-feature-of-vlc,VLC player
215dfd39-f493-4bc3-a027-8a97d72c61bf,https://superuser.com/questions/1224784/how-to-change-vlcs-splash-screen,VLC player
bb5e4c0d-f964-439c-97b6-bdb9747de3f4,https://www.wikihow.com/Remove-an-Email-Account-from-Thunderbird,ThunderBird
7b6c7e24-c58a-49fc-a5bb-d57b80e5b4c3,https://www.wikihow.com/Access-Gmail-With-Mozilla-Thunderbird,ThunderBird
b188fe10-ae67-4db8-a154-26a0b8ff8f1e,https://www.reddit.com/r/Thunderbird/comments/17vv2os/restore_readability_in_message_list_pane/,ThunderBird
12086550-11c0-466b-b367-1d9e75b3910e,https://www.bitrecover.com/blog/manage-thunderbird-profiles/,ThunderBird
06fe7178-4491-4589-810f-2e2bc9502122,https://www.quora.com/How-do-I-backup-email-files-in-Mozilla-Thunderbird,ThunderBird
6766f2b8-8a72-417f-a9e5-56fcaa735837,"https://www.adsigner.com/user-manual/signatures/setup-email-client-thunderbird/#:~:text=is%20probably%20hidden.-,Right%20click%20on%20the%20empty%20space%20at%20the%20top%20of,signature%20from%20a%20file%20instead.",ThunderBird
e1e75309-3ddb-4d09-92ec-de869c928143,https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters,ThunderBird
3d1682a7-0fb0-49ae-a4dc-a73afd2d06d5,https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters,ThunderBird
35253b65-1c19-4304-8aa4-6884b8218fc0,https://support.mozilla.org/en-US/questions/1259354,ThunderBird
d088f539-cab4-4f9a-ac92-9999fc3a656e,https://support.mozilla.org/en-US/kb/how-use-attachments,ThunderBird
2ad9387a-65d8-4e33-ad5b-7580065a27ca,"https://support.mozilla.org/bm/questions/1027435, https://www.wikihow.tech/Create-Folders-in-Mozilla-Thunderbird",ThunderBird
480bcfea-d68f-4aaa-a0a9-2589ef319381,https://www.reddit.com/r/Thunderbird/comments/182dg5p/unified_inbox_howto/,ThunderBird
37b9808f-b2b4-4177-ab00-9ddfae4bad27,https://www.quora.com/How-can-I-schedule-Mozilla-Thunderbird-to-turn-off-automatically,ThunderBird
af630914-714e-4a24-a7bb-f9af687d3b91,https://stackoverflow.com/questions/11333148/adding-a-toolbar-button-to-a-thundebird-compose-message-window?rq=3,ThunderBird
3299584d-8f11-4457-bf4c-ce98f7600250,https://superuser.com/questions/1643561/would-like-to-see-the-email-address-from-sender-in-the-column,ThunderBird
030eeff7-b492-4218-b312-701ec99ee0cc,https://superuser.com/questions/1781004/how-do-i-remove-the-indentation-and-character-in-quoted-text-of-a-reply-mess,ThunderBird
94760984-3ff5-41ee-8347-cf1af709fea0,https://superuser.com/questions/1757333/how-can-i-view-thunderbird-in-full-dark-mode,ThunderBird
99146c54-4f37-4ab8-9327-5f3291665e1e,https://superuser.com/questions/1764409/how-to-send-email-with-thunderbird-without-configuring-an-incoming-email-service,ThunderBird
9656a811-9b5b-4ddf-99c7-5117bcef0626,https://superuser.com/questions/205240/is-there-a-way-to-get-a-popup-confirmation-box-when-you-send-an-email-in-thunder?rq=1,ThunderBird
c9e7eaf2-b1a1-4efc-a982-721972fa9f02,https://superuser.com/questions/544480/how-to-apply-automatic-message-filters-to-subfolders-too?noredirect=1&lq=1,ThunderBird
bb5e4c0d-f964-439c-97b6-bdb9747de3f4,https://support.google.com/chrome/answer/95426?sjid=16867045591165135686-AP,Chrome
7b6c7e24-c58a-49fc-a5bb-d57b80e5b4c3,https://support.google.com/chrome/answer/95647?hl=en&ref_topic=7438325&sjid=16867045591165135686-AP#zippy=%2Cdelete-cookies-from-a-site,Chrome
12086550-11c0-466b-b367-1d9e75b3910e,https://www.quora.com/What-are-the-cool-tricks-to-use-Google-Chrome,Chrome
06fe7178-4491-4589-810f-2e2bc9502122,https://www.wikihow.com/Switch-Tabs-in-Chrome,Chrome
6766f2b8-8a72-417f-a9e5-56fcaa735837,https://support.google.com/chrome/thread/205881926/it-s-possible-to-load-unpacked-extension-automatically-in-chrome?hl=en,Chrome
e1e75309-3ddb-4d09-92ec-de869c928143,https://in5stepstutorials.com/google-chrome/save-web-page-as-pdf-in-chrome.php,Chrome
3d1682a7-0fb0-49ae-a4dc-a73afd2d06d5,https://in5stepstutorials.com/google-chrome/add-change-delete-autofill-address.php,Chrome
35253b65-1c19-4304-8aa4-6884b8218fc0,"https://www.laptopmag.com/articles/how-to-create-desktop-shortcuts-for-web-pages-using-chrome, https://www.reddit.com/r/chrome/comments/13xcbap/crete_shortcut_option_missing/",Chrome
d088f539-cab4-4f9a-ac92-9999fc3a656e,https://medium.com/@inkverseuk2/useful-tips-and-tricks-for-the-google-chrome-browser-ac7d0d24b3cc,Chrome
2ad9387a-65d8-4e33-ad5b-7580065a27ca,https://www.youtube.com/watch?v=IN-Eq_UripQ,Chrome
7a5a7856-f1b6-42a4-ade9-1ca81ca0f263,https://www.youtube.com/watch?v=ZaZ8GcTxjXA,Chrome
3720f614-37fd-4d04-8a6b-76f54f8c222d,https://superuser.com/questions/984668/change-interface-language-of-chrome-to-english,Chrome
b63059a2-53bc-4163-a89f-3ac948c74081,https://superuser.com/questions/1303418/how-do-i-make-chrome-block-absolutely-all-pop-ups?rq=1,Chrome
44ee5668-ecd5-4366-a6ce-c1c9b8d4e938,https://superuser.com/questions/1787991/clear-browsing-history-from-specific-site-on-chrome,Chrome
b5ebc8c6-6329-4373-85b4-9421c97375e9,https://superuser.com/questions/364470/is-there-a-way-to-view-google-chrome-browsing-history-past-three-months-ago?rq=1,Chrome
93eabf48-6a27-4cb6-b963-7d5fe1e0d3a9,https://superuser.com/questions/1417973/how-to-disable-google-chrome-dark-mode,Chrome
2ae9ba84-3a0d-4d4c-8338-3a1478dc5fe3,https://superuser.com/questions/1393683/how-to-change-the-username-in-google-chrome-profiles?rq=1,Chrome
480bcfea-d68f-4aaa-a0a9-2589ef319381,https://bugartisan.medium.com/disable-the-new-chrome-ui-round-in-2023-db168271f71e,Chrome
37b9808f-b2b4-4177-ab00-9ddfae4bad27,https://www.reddit.com/r/chrome/comments/17niw3h/tutorial_how_to_disable_the_download_bubble_in/,Chrome
af630914-714e-4a24-a7bb-f9af687d3b91,https://www.howtogeek.com/680260/how-to-change-chromes-default-text-size/,Chrome
ae78f875-5b98-4907-bbb5-9c737fc68c03,https://support.google.com/chrome/thread/219988391/increase-search-results-per-page?hl=en,Chrome
0ed39f63-6049-43d4-ba4d-5fa2fe04a951,https://www.quora.com/How-do-you-find-and-replace-text-in-Visual-Studio-Code,VS Code
b421106e-b282-4c41-af72-37c95493f95f,https://stackoverflow.com/questions/74153883/launch-vscode-with-new-txt-file,VS Code
53ad5833-3455-407b-bbc6-45b4c79ab8fb,https://www.youtube.com/watch?v=VqCgcpAypFQ,VS Code
eabc805a-bfcf-4460-b250-ac92135819f6,https://www.youtube.com/watch?v=VqCgcpAypFQ,VS Code
3486f395-ad68-459c-8c39-ea07de934dd4,https://www.youtube.com/watch?v=VqCgcpAypFQ,VS Code
982d12a5-beab-424f-8d38-d2a48429e511,https://www.youtube.com/watch?v=ORrELERGIHs,VS Code
4e60007a-f5be-4bfc-9723-c39affa0a6d3,"https://campbell-muscle-lab.github.io/howtos_Python/pages/documentation/best_practices/vscode_docstring_extension/vscode_docstring_extension.html#:~:text=Type%2C%20Ctrl%20%2B%20Shift%20%2B%20P,select%20the%20NumPy%20docstring%20format.",VS Code
e2b5e914-ffe1-44d2-8e92-58f8c5d92bb2,https://superuser.com/questions/1386061/how-to-suppress-some-python-errors-warnings-in-vs-code,VS Code
9439a27b-18ae-42d8-9778-5f68f891805e,https://stackoverflow.com/questions/75832474/how-to-keep-cursor-in-debug-console-when-debugging-in-visual-studio-code,VS Code
ae506c68-352c-4094-9caa-ee9d42052317,https://superuser.com/questions/1460404/get-visual-studio-code-terminal-history?rq=1,VS Code
ea98c5d7-3cf9-4f9b-8ad3-366b58e0fcae,https://superuser.com/questions/1748097/vs-code-disable-tree-view-find-explorer-search,VS Code
c714dcee-cad3-4e12-8f3c-12bdcfcdb048,https://superuser.com/questions/1417361/how-to-disable-file-filtering-in-vs-code-sidebar-explorer?rq=1,VS Code
930fdb3b-11a8-46fe-9bac-577332e2640e,https://superuser.com/questions/1270103/how-to-switch-the-cursor-between-terminal-and-code-in-vscode,VS Code
276cc624-87ea-4f08-ab93-f770e3790175,https://www.quora.com/unanswered/How-do-you-set-the-line-length-in-Visual-Studio-Code,VS Code
9d425400-e9b2-4424-9a4b-d4c7abac4140,https://superuser.com/questions/1466771/is-there-a-way-to-make-editor-tabs-stack-in-vs-code,VS Code
7a4deb26-d57d-4ea9-9a73-630f66a7b568,https://www.quora.com/How-do-I-edit-a-photo-in-GIMP,GIMP
554785e9-4523-4e7a-b8e1-8016f565f56a,https://www.quora.com/How-do-I-edit-a-photo-in-GIMP,GIMP
77b8ab4d-994f-43ac-8930-8ca087d7c4b4,https://superuser.com/questions/1636113/how-to-get-gimp-to-recognize-images-or-pictures-folder-as-the-default-folder-for,GIMP
f4aec372-4fb0-4df5-a52b-79e0e2a5d6ce,https://superuser.com/questions/612338/how-do-i-select-and-move-an-object-in-gimp,GIMP
d52d6308-ec58-42b7-a2c9-de80e4837b2b,https://superuser.com/questions/1447106/how-to-get-rid-of-the-gimp-tool-options-box,GIMP
2a729ded-3296-423d-aec4-7dd55ed5fbb3,https://www.youtube.com/watch?v=lOzSiOIipSM,GIMP
b148e375-fe0b-4bec-90e7-38632b0d73c2,https://www.quora.com/How-do-I-add-layers-in-GIMP,GIMP
a746add2-cab0-4740-ac36-c3769d9bfb46,https://www.youtube.com/watch?v=_L_MMU22bAw,GIMP
7b7617bd-57cc-468e-9c91-40c4ec2bcb3d,https://www.youtube.com/watch?v=G_PjQAy0iiU,GIMP
d16c99dc-2a1e-46f2-b350-d97c86c85c15,https://stackoverflow.com/questions/75185543/use-gimp-to-resize-image-in-one-layer-only,GIMP
573f79b5-abfe-4507-b455-251d45fe6198,https://stackoverflow.com/questions/45196895/gimp-add-padding-to-multiple-images,GIMP
06ca5602-62ca-47f6-ad4f-da151cde54cc,https://stackoverflow.com/questions/74664666/how-to-export-palette-based-png-in-gimp,GIMP
fa9b1e10-4d2d-4a13-af76-7efa822b6a8b,https://stackoverflow.com/questions/24626608/how-to-combine-several-png-images-as-layers-in-a-single-xcf-image,GIMP
6b2b72ed-3a10-4849-876a-750f7cdf3886,https://stackoverflow.com/questions/21018007/resize-image-to-fit-canvas-gimp,GIMP
d0e42fd2-d290-46b3-b598-a6e2b7be9c85,https://stackoverflow.com/questions/56758689/stop-gimp-from-merging-layers-when-de-selecting,GIMP
e2dd0213-26db-4349-abe5-d5667bfd725c,https://superuser.com/questions/839650/how-to-move-an-inserted-text-box-in-gimp,GIMP
f723c744-e62c-4ae6-98d1-750d3cd7d79d,https://www.reddit.com/r/GIMP/comments/12e57w8/how_to_use_gimp_to_exaggerate_contrast/,GIMP
8d6b1c9c-1aab-47fe-9ba5-e84c838d0c57,https://www.quora.com/How-can-email-attachments-be-converted-into-a-word-document-using-Mozilla-Thunderbird,multiple
11e1e614-9696-4d94-88c9-8e556880d41a,https://ifttt.com/applets/L2A89geP-send-chrome-software-update-release-alerts-to-email,multiple
57956154-f0fe-486b-88b8-e7126da035a9,https://zapier.com/apps/email/integrations/google-sheets/547/get-email-notifications-for-new-rows-in-a-google-sheets-spreadsheet,multiple
ec14c524-b245-456d-abd6-ec12c746e9f8,https://zapier.com/apps/gmail/integrations/google-sheets/2618/save-new-gmail-emails-matching-certain-traits-to-a-google-spreadsheet,multiple
cbf5fbda-425e-4619-bcf2-0ea8d4c0bfa3,https://zapier.com/apps/google-sheets/integrations/google-slides/13919/refresh-charts-on-a-google-slides-presentation-when-rows-are-updated-on-google-sheets,multiple
a54284d0-7b93-4327-bfcc-3a421516dbdd,https://superuser.com/questions/655622/cannot-drag-images-from-thunderbird-to-word,multiple
58565672-7bfe-48ab-b828-db349231de6b,https://superuser.com/questions/1792660/open-link-from-other-application-does-not-open-the-url-in-firefox,multiple
6d72aad6-187a-4392-a4c4-ed87269c51cf,https://superuser.com/questions/923171/converting-openoffice-impress-presentation-to-video-without-screen-recording,multiple
937087b6-f668-4ba6-9110-60682ee33441,https://superuser.com/questions/187440/set-default-ubuntu-video-player-as-vlc,multiple
f8cfa149-d1c1-4215-8dac-4a0932bad3c2,https://superuser.com/questions/1803088/libreoffice-calc-clears-clipboard,multiple
5e974913-6905-4c3f-8b65-d7837f3931cc,https://stackoverflow.com/questions/61856141/how-can-i-start-thunderbird-and-minimize-the-window-on-startup-in-ubuntu,multiple
7c179dad-f1c7-4892-b53f-d1c4023d23c7,https://stackoverflow.com/questions/21155085/pasting-excel-tables-in-thunderbird-e-mail-client,multiple
4a68b2dd-70f2-4532-9bc1-d21878bd8cb2,https://stackoverflow.com/questions/65669955/thunderbird-how-to-send-a-mail-to-all-receivers-of-a-folder,multiple
c8457fde-b14b-4aba-b402-144842ea29e1,https://stackoverflow.com/questions/65788200/how-to-open-xlsx-files-in-ms-excel-from-vs-code,multiple
81c425f5-78f3-4771-afd6-3d2973825947,https://www.zyxware.com/articles/3770/how-to-transfer-data-in-libreoffice-calc-to-libreoffice-writer-in-table-format,multiple
bb83cab4-e5c7-42c7-a67b-e46068032b86,https://ask.libreoffice.org/t/save-impress-presentation-as-writer-document/5291/4,multiple
227d2f97-562b-4ccb-ae47-a5ec9e142fbb,https://discourse.gnome.org/t/gimp-and-libre-office-writer/15430/4,multiple
a6bbc08c-51e9-4ee4-9327-83d05075d960,https://forum.openoffice.org/en/forum/viewtopic.php?t=105055,multiple
964e6e03-ba31-466b-8c15-5a351a81f675,https://www.maketecheasier.com/mail-merge-thunderbird-calc/,multiple
2fe4b718-3bd7-46ec-bdce-b184f5653624,https://www.thewindowsclub.com/how-to-create-animated-gif-from-a-video-file-using-vlc-and-gimp,multiple
d02b9364-6bb0-4c7e-9dbd-4db62822bc26,https://stackoverflow.com/questions/38306910/simple-python-script-to-get-a-libreoffice-base-field-and-play-on-vlc,multiple
57fb469b-127a-46fa-8281-bbb3840efdf5,https://support.mozilla.org/en-US/questions/1150626,multiple
3680a5ee-6870-426a-a997-eba929a0d25c,https://unix.stackexchange.com/questions/510850/how-to-open-calc-from-terminal-and-insert-files,multiple
2d8c8a20-6f54-4c2e-ad56-61fbe7af6b78,https://www.quora.com/How-do-I-force-LibreOffice-Calc-to-recalculate-a-spreadsheet-from-the-command-line,multiple
ee9a3c83-f437-4879-8918-be5efbb9fac7,https://stackoverflow.com/questions/64589140/convert-ods-to-csv-using-command-line-when-libreoffice-instance-is-running,multiple
f7dfbef3-7697-431c-883a-db8583a4e4f9,https://www.thegeekdiary.com/libreoffice-command-examples-in-linux/,multiple
2b9493d7-49b8-493a-a71b-56cd1f4d6908,https://devicetests.com/kill-libreoffice-writer-command-line-ubuntu,multiple
51f5801c-18b3-4f25-b0c3-02f85507a078,https://github.com/danielrcollins1/ImpressExtractNotes,multiple
81de345e-5473-4cb6-a74d-b6abf3475a6a,https://stackoverflow.com/questions/45588952/how-can-i-compose-and-send-email-in-thunderbird-from-commandline,multiple
2c9fc0de-3ee7-45e1-a5df-c86206ad78b5,https://nikki-ricks.medium.com/how-to-use-git-add-commit-and-push-in-vs-code-and-command-line-35c0e8c47b62,multiple
510f64c8-9bcc-4be1-8d30-638705850618,https://www.geeksforgeeks.org/how-to-start-vs-code-from-the-terminal-command-line/,multiple
9ff484f7-5c09-4398-ae29-d5904e59e138,https://stackoverflow.com/questions/38606973/playing-opening-and-pausing-vlc-command-line-executed-from-python-scripts,multiple
d9b7c649-c975-4f53-88f5-940b29c47247,https://marketplace.uipath.com/listings/extract-the-first-1000-gmail-emails-from-the-current-month-in-a-new-google-sheets-report,multiple
be4ef0dc-0f70-4936-81d8-3cd2b04482f8,https://marketplace.uipath.com/listings/table-data-extraction-for-sales-opportunities-to-excel-workbook,multiple
78aed49a-a710-4321-a793-b611a7c5b56b,https://marketplace.uipath.com/listings/upload-email-attachments-from-gmail-to-google-drive,multiple
897e3b53-5d4d-444b-85cb-2cdc8a97d903,https://marketplace.uipath.com/listings/convert-word-file-to-pdf-and-store-in-onedrive,multiple
4e9f0faf-2ecc-4ae8-a804-28c9a75d1ddc,https://marketplace.uipath.com/listings/extract-data-from-a-new-invoice-file-in-google-drive-and-store-it-in-google-sheets4473,multiple
b52b40a5-ad70-4c53-b5b0-5650a8387052,https://marketplace.uipath.com/listings/merge-pdfs-from-gmail-email-attachments-and-upload-to-gogle-drive,multiple
46407397-a7d5-4c6b-92c6-dbe038b1457b,https://marketplace.uipath.com/listings/upload-to-google-drive-images-from-pdf-attachments-received-via-gmail,multiple
a0b9dc9c-fc07-4a88-8c5d-5e3ecad91bcb,https://marketplace.uipath.com/listings/backup-important-emails-to-onedrive-or-sharepoint,multiple
665f4af1-617d-4009-baff-84ff66071e6a,https://www.howtogeek.com/663927/how-to-open-google-chrome-using-command-prompt-on-windows-10/#open-chrome-straight-to-a-specific-website,multiple
e6313b30-3903-4ed9-8c7d-4c47bf51fc96,https://stackoverflow.com/questions/12258086/how-do-i-run-google-chrome-as-root,multiple
1 id Source InvolvedApp
2 94d95f96-9699-4208-98ba-3c3119edf9c2 https://help.ubuntu.com/lts/ubuntu-help/addremove-install.html.en OS
3 bedcedc4-4d72-425e-ad62-21960b11fe0d https://www.youtube.com/watch?v=D4WyNjt_hbQ&t=2s OS
4 43c2d64c-bab5-4dcb-a30c-b888321c319a https://ubuntu.com/tutorials/command-line-for-beginners#4-creating-folders-and-files OS
5 7688b85f-87a4-4e4a-b2f8-f3d6c3f29b82 https://ubuntu.com/tutorials/command-line-for-beginners#5-moving-and-manipulating-files OS
6 ec4e3f68-9ea4-4c18-a5c9-69f89d1178b3 https://www.youtube.com/watch?v=D4WyNjt_hbQ&t=2s OS
7 a462a795-fdc7-4b23-b689-e8b6df786b78 https://help.ubuntu.com/lts/ubuntu-help/shell-exit.html.en OS
8 f9be0997-4b7c-45c5-b05c-4612b44a6118 https://help.ubuntu.com/lts/ubuntu-help/shell-notifications.html.en OS
9 ae039631-2b12-4637-84f6-c67d51511be3 https://help.ubuntu.com/lts/ubuntu-help/net-default-browser.html.en OS
10 e2eb4bf1-aa93-4192-b55d-03e2fb6dfd15 https://help.ubuntu.com/lts/ubuntu-help/contacts-add-remove.html.en OS
11 28cc3b7e-b194-4bc9-8353-d04c0f4d56d2 https://help.ubuntu.com/lts/ubuntu-help/sound-volume.html.en OS
12 5ea617a3-0e86-4ba6-aab2-dac9aa2e8d57 https://help.ubuntu.com/lts/ubuntu-help/files-recover.html.en OS
13 e0df059f-28a6-4169-924f-b9623e7184cc https://help.ubuntu.com/lts/ubuntu-help/files-rename.html.en OS
14 ddc75b62-7311-4af8-bfb3-859558542b36 https://help.ubuntu.com/lts/ubuntu-help/addremove-remove.html.en OS
15 5c433d22-ed9a-4e31-91f5-54cf3e8acd63 https://help.ubuntu.com/lts/ubuntu-help/session-language.html.zh-CN OS
16 b6781586-6346-41cd-935a-a6b1487918fc https://help.ubuntu.com/lts/ubuntu-help/clock-timezone.html.en OS
17 b3d4a89c-53f2-4d6b-8b6a-541fb5d205fa https://help.ubuntu.com/lts/ubuntu-help/bluetooth-turn-on-off.html.en OS
18 3ce045a0-877b-42aa-8d2c-b4a863336ab8 https://help.ubuntu.com/lts/ubuntu-help/a11y-font-size.html.en OS
19 fe41f596-a71b-4c2f-9b2f-9dcd40b568c3 https://help.ubuntu.com/lts/ubuntu-help/power-percentage.html.en OS
20 a4d98375-215b-4a4d-aee9-3d4370fccc41 https://help.ubuntu.com/lts/ubuntu-help/privacy-screen-lock.html.en OS
21 765d2b74-88a7-4d50-bf51-34e4106fd24a https://help.ubuntu.com/lts/ubuntu-help/files-delete.html.en OS
22 cc9d4f34-1ca0-4a1b-8ff2-09302696acb9 https://superuser.com/questions/178587/how-do-i-detach-a-process-from-terminal-entirely OS
23 5812b315-e7bd-4265-b51f-863c02174c28 https://superuser.com/questions/149404/create-an-ssh-user-who-only-has-permission-to-access-specific-folders OS
24 c56de254-a3ec-414e-81a6-83d2ce8c41fa https://superuser.com/questions/28426/how-to-extract-text-with-ocr-from-a-pdf-on-linux OS
25 6ebbfb01-ea72-4226-a2a6-dc428e111ed2 https://superuser.com/questions/46748/how-do-i-make-bash-my-default-shell-on-ubuntu OS
26 4d2b519e-e872-4100-8ea3-fe71ab0f9133 https://stackoverflow.com/questions/11530090/adding-a-new-entry-to-the-path-variable-in-zsh OS
27 c288e301-e626-4b98-a1ab-159dcb162af5 https://stackoverflow.com/questions/41986507/unable-to-set-default-python-version-to-python3-in-ubuntu OS
28 13584542-872b-42d8-b299-866967b5c3ef https://superuser.com/questions/72176/linux-set-default-terminal-size-and-screen-position OS
29 23393935-50c7-4a86-aeea-2b78fd089c5c https://superuser.com/questions/91307/copying-only-jpg-from-a-directory-structure-to-another-location-linux OS
30 f10b16e1-c160-4cb3-989f-7b2ec89bc073 https://www.wikihow.com/Install-Gnome-on-Ubuntu OS
31 eb03d19a-b88d-4de4-8a64-ca0ac66f426b https://www.youtube.com/shorts/t9JLUaT55UQ MS Excel
32 0bf05a7d-b28b-44d2-955a-50b41e24012a https://www.youtube.com/shorts/FPAQaDTS8VY MS Excel
33 7b802dad-6e0f-4204-9815-d4e3f57627d8 https://www.youtube.com/shorts/Of-lzeP1usE MS Excel
34 7a4e4bc8-922c-4c84-865c-25ba34136be1 https://www.youtube.com/shorts/bvUhr1AHs44 MS Excel
35 2bd59342-0664-4ccb-ba87-79379096cc08 https://www.youtube.com/shorts/L3Z-F1QTQFY MS Excel
36 a9f325aa-8c05-4e4f-8341-9e4358565f4f https://www.youtube.com/shorts/A0gmEBRKXWs MS Excel
37 ecb0df7a-4e8d-4a03-b162-053391d3afaf https://www.youtube.com/shorts/tXOovKn0H68 MS Excel
38 7efeb4b1-3d19-4762-b163-63328d66303b https://www.youtube.com/shorts/4jzXfZNhfmk MS Excel
39 4e6fcf72-daf3-439f-a232-c434ce416af6 https://www.youtube.com/shorts/0uxJccNCKcE MS Excel
40 6054afcb-5bab-4702-90a0-b259b5d3217c https://www.youtube.com/shorts/JTbZ8sRxkdU MS Excel
41 abed40dc-063f-4598-8ba5-9fe749c0615d https://www.youtube.com/shorts/xgf4ZpsEx5M MS Excel
42 01b269ae-2111-4a07-81fd-3fcd711993b0 https://www.youtube.com/shorts/VrUzPTIwQ04 MS Excel
43 8b1ce5f2-59d2-4dcc-b0b0-666a714b9a14 https://www.youtube.com/shorts/Hbcwu6IQ1ns MS Excel
44 af2b02f7-acee-4be4-8b66-499fab394915 https://www.youtube.com/shorts/AwKsb5VmtBI MS Excel
45 da1d63b8-fa12-417b-ba18-f748e5f770f3 https://www.youtube.com/shorts/hquscnbz2-U MS Excel
46 636380ea-d5f6-4474-b6ca-b2ed578a20f1 https://www.youtube.com/shorts/_BYL6VOHLGw MS Excel, Edge
47 5ba77536-05c5-4aae-a9ff-6e298d094c3e https://www.youtube.com/shorts/CuBC1evUS5I MS Excel
48 4bc4eaf4-ca5e-4db2-8138-8d4e65af7c0b https://www.youtube.com/shorts/1adQWfjN-tI MS Excel
49 672a1b02-c62f-4ae2-acf0-37f5fb3052b0 https://www.youtube.com/shorts/2rhdQXI4Lng MS Excel
50 648fe544-16ba-44af-a587-12ccbe280ea6 https://www.youtube.com/shorts/sOPBMWaC6Uc MS Excel
51 8985d1e4-5b99-4711-add4-88949ebb2308 https://www.youtube.com/shorts/J5ts2Acv9Pc MS Excel
52 9e606842-2e27-43bf-b1d1-b43289c9589b https://www.youtube.com/shorts/B-mGYDFOyUs MS Excel
53 fcb6e45b-25c4-4087-9483-03d714f473a9 https://www.youtube.com/shorts/GZipp7nOZS0 MS Excel
54 68c0c5b7-96f3-4e87-92a7-6c1b967fd2d2 https://www.youtube.com/shorts/JEH5TsK-cCk MS Excel, Edge
55 fff629ea-046e-4793-8eec-1a5a15c3eb35 https://www.youtube.com/shorts/8WybtCdUT6w MS Excel
56 5c9a206c-bb00-4fb6-bb46-ee675c187df5 https://www.youtube.com/shorts/VbQtMNnq9i4 MS Excel
57 e975ae74-79bd-4672-8d1c-dc841a85781d https://www.youtube.com/shorts/GjT7gGe5Sr8 MS Excel
58 34a6938a-58da-4897-8639-9b90d6db5391 https://www.youtube.com/shorts/gW37x2TkzOY MS Excel
59 b5a22759-b4eb-4bf2-aeed-ad14e8615f19 https://www.youtube.com/shorts/3xLa-D0C7Ic MS Excel
60 2f9913a1-51ed-4db6-bfe0-7e1c95b3139e https://www.youtube.com/shorts/dGLRcmfVO6Q MS Excel
61 2558031e-401d-4579-8e00-3ecf540fb492 https://www.mrexcel.com/board/threads/sales-for-the-first-6-weeks.1249213/ MS Excel
62 39aa4e37-dc91-482e-99af-132a612d40f3 https://www.libreofficehelp.com/add-insert-delete-copy-move-rename-a-worksheet-in-libreoffice-calc/ LibreOffice Calc
63 0cecd4f3-74de-457b-ba94-29ad6b5dafb6 https://www.libreofficehelp.com/add-insert-delete-copy-move-rename-a-worksheet-in-libreoffice-calc/ LibreOffice Calc
64 4188d3a4-077d-46b7-9c86-23e1a036f6c1 https://www.libreofficehelp.com/freeze-unfreeze-rows-columns-ranges-calc/ LibreOffice Calc
65 51b11269-2ca8-4b2a-9163-f21758420e78 https://www.reddit.com/r/LibreOfficeCalc/comments/186pcc6/how_to_arrange_numbers_in_a_column_from_minimum/ LibreOffice Calc
66 7e429b8d-a3f0-4ed0-9b58-08957d00b127 https://medium.com/@divyangichaudhari17/how-to-use-vlookup-and-hlookup-in-libre-calc-3370698bb3ff LibreOffice Calc
67 f5a90742-3fa2-40fc-a564-f29b054e0337 https://superuser.com/questions/1236149/libreoffice-calc-how-to-apply-functions-to-columns LibreOffice Calc
68 22df9241-f8d7-4509-b7f1-37e501a823f7 https://superuser.com/questions/1767185/how-do-you-move-cells-in-libreoffice-calc LibreOffice Calc
69 1434ca3e-f9e3-4db8-9ca7-b4c653be7d17 https://www.wikihow.com/Remove-Duplicates-in-Open-Office-Calc LibreOffice Calc
70 347ef137-7eeb-4c80-a3bb-0951f26a8aff https://www.youtube.com/watch?v=bgO40-CjYNY LibreOffice Calc
71 6e99a1ad-07d2-4b66-a1ce-ece6d99c20a5 https://www.youtube.com/watch?v=nl-nXjJurhQ LibreOffice Calc
72 3aaa4e37-dc91-482e-99af-132a612d40f3 https://www.quora.com/How-can-you-import-export-CSV-files-with-LibreOffice-Calc-or-OpenOffice LibreOffice Calc
73 0decd4f3-74de-457b-ba94-29ad6b5dafb6 https://justclickhere.co.uk/resources/checkboxes-tick-boxes-libreoffice-calc/ LibreOffice Calc
74 37608790-6147-45d0-9f20-1137bb35703d https://www.youtube.com/shorts/uzPo_CPCHH8 MS Excel
75 f9584479-3d0d-4c79-affa-9ad7afdd8850 https://youtube.com/shorts/feldd-Pn48c?si=9xJiem2uAHm6Jshb LibreOffice Calc
76 d681960f-7bc3-4286-9913-a8812ba3261a https://www.youtube.com/shorts/d7U1S_IsTVM LibreOffice Calc
77 f6a90742-3fa2-40fc-a564-f29b054e0337 https://www.excel-easy.com/examples/drop-down-list.html LibreOffice Calc
78 21df9241-f8d7-4509-b7f1-37e501a823f7 https://www.youtube.com/watch?v=p5C4V_AO1UU LibreOffice Calc
79 1334ca3e-f9e3-4db8-9ca7-b4c653be7d17 https://techcommunity.microsoft.com/t5/excel/excel-workbook-top-way-too-big-can-t-see-rows-and-columns/m-p/4014694 LibreOffice Calc
80 357ef137-7eeb-4c80-a3bb-0951f26a8aff https://www.reddit.com/r/excel/comments/17zny8u/calculating_total_amount_earned_from_total_hours/ LibreOffice Calc
81 6f99a1ad-07d2-4b66-a1ce-ece6d99c20a5 https://techcommunity.microsoft.com/t5/excel/sumarize-the-sheetnames/m-p/4014716 LibreOffice Calc
82 aa3a8974-2e85-438b-b29e-a64df44deb4b https://www.quora.com/Libre-Office-Calc-How-do-I-resize-all-cells-in-a-sheet-to-make-them-fit-to-1-page-for-printing-and-exporting-as-PDF LibreOffice Calc
83 a01fbce3-2793-461f-ab86-43680ccbae25 https://superuser.com/questions/1250677/how-to-set-decimal-separator-in-libre-office-calc LibreOffice Calc
84 4f07fbe9-70de-4927-a4d5-bb28bc12c52c https://superuser.com/questions/1081048/libreoffice-calc-how-to-pad-number-to-fixed-decimals-when-used-within-formula LibreOffice Calc
85 e3b1d5fa-ed00-4129-bda1-1452bd2b6772 https://www.reddit.com/r/libreoffice/comments/tel112/calc_how_to_calculate_sum_by_categories/ LibreOffice Calc
86 ca6a9524-f8e9-4d2f-9364-ab0cad567739 https://www.reddit.com/r/libreoffice/comments/113gmyc/how_to_remove_certain_text_from_cells_in_calc/ LibreOffice Calc
87 a455e8d0-930f-40d2-9575-5e8d2d222f58 https://superuser.com/questions/562944/quickly-fill-blank-cells-in-a-list-in-libreoffice-calc LibreOffice Calc
88 83ee22c6-7737-49ce-9b5a-138c3e92af04 https://superuser.com/questions/661102/currency-conversion-in-libreoffice-calc LibreOffice Calc
89 819f61c2-ec77-4d3f-9996-0838ae5aacc8 https://superuser.com/questions/381696/creating-a-column-of-working-days-in-libreoffice-calc LibreOffice Calc
90 69d577b3-004e-4bca-89b2-0d7c2f6049e3 https://superuser.com/questions/387106/libreoffice-calc-how-to-get-total-for-hhmmss-cells LibreOffice Calc
91 0a1bf4ca-d4ea-4618-baa5-6e8dc1b46d82 https://superuser.com/questions/571915/sum-up-to-n-highest-value-out-of-a-series LibreOffice Calc
92 ac9bb6cb-1888-43ab-81e4-a98a547918cd https://superuser.com/questions/1674211/how-to-change-colour-of-slide-number-in-libre-office LibreOffice Impress
93 5d901039-a89c-4bfb-967b-bf66f4df075e https://superuser.com/questions/986776/how-can-i-stretch-an-image-in-a-libreoffice-impress-presentation-to-fill-the-pag LibreOffice Impress
94 071d4ace-091a-4ec3-886e-f4be55ae375d https://superuser.com/questions/706860/hide-slide-numbers-and-slide-footer-on-first-and-second-slide-in-libreoffice-imp?rq=1 LibreOffice Impress
95 550ce7e7-747b-495f-b122-acdc4d0b8e54 https://technical-tips.com/blog/software/text-in-libreoffice-strikethrough--6948#:~:text=To%20strikethrough%20Text%20in%20LibreOffice%201%20In%20your,effect%22%20can%20your%20additionally%2C%20for%20example%2C%20double%20underline. LibreOffice Impress
96 455d3c66-7dc6-4537-a39a-36d3e9119df7 https://www.libreofficehelp.com/export-libreoffice-impress-slides-images/#:~:text=Exporting%20a%20single%20slide%20as.jpg%2C.png%2C%20etc%20image%20is,on%20the%20checkbox%20Selection.%20Provide%20jpg%20quality%20options. LibreOffice Impress
97 af23762e-2bfd-4a1d-aada-20fa8de9ce07 https://superuser.com/questions/1059080/how-to-make-a-summary-slide-in-impress-listing-the-titles-of-all-slides-autom LibreOffice Impress
98 c59742c0-4323-4b9d-8a02-723c251deaa0 https://www.reddit.com/r/libreoffice/comments/17lcdrp/audio_not_supported_in_libreoffice_impress/ LibreOffice Impress
99 39478d4a-1049-456f-aa77-407811393add https://www.reddit.com/r/libreoffice/comments/jul3o8/putting_cap_or_hat_or_carat_symbol_in_libre/ LibreOffice Impress
100 c3ad4442-499f-4e58-bc4e-1a1417ea9b8c http://maharajacollege.ac.in/material/Libreofficeimpresspdf.pdf LibreOffice Impress
101 ef9d12bd-bcee-4ba0-a40e-918400f43ddf https://www.reddit.com/r/libreoffice/comments/18elh3y/i_closed_the_slide_pannel_on_the_left_and_idk_how/ LibreOffice Impress
102 9ec204e4-f0a3-42f8-8458-b772a6797cab https://www.tiktok.com/@lil.d1rt_/video/7247574148887629083 LibreOffice Impress
103 0f84bef9-9790-432e-92b7-eece357603fb https://stackoverflow.com/questions/29036788/how-to-disable-libreoffice-impress-to-use-multiple-display LibreOffice Impress
104 ce88f674-ab7a-43da-9201-468d38539e4a https://justclickhere.co.uk/resources/change-slides-in-impress-to-portrait/ LibreOffice Impress
105 f0a334af-f91b-4c03-b578-aac9bec2b543 https://www.libreofficehelp.com/insert-video-impress-presentation/#Inserting_a_Video_in_Impress LibreOffice Impress
106 3b27600c-3668-4abd-8f84-7bcdebbccbdb https://www.libreofficehelp.com/change-slide-background-impress/#All_Slides LibreOffice Impress
107 a097acff-6266-4291-9fbd-137af7ecd439 https://www.youtube.com/watch?v=DDmEvjs4iBw LibreOffice Impress
108 21760ecb-8f62-40d2-8d85-0cee5725cb72 https://www.libreofficehelp.com/add-animations-transitions-libreoffice-impress-slides/ LibreOffice Impress
109 3cc4f35d-fa2e-4555-afb9-741b7c062a74 https://documentation.libreoffice.org/assets/Uploads/Documentation/en/IG7.6/IG76-ImpressGuide.pdf LibreOffice Impress
110 6ada715d-3aae-4a32-a6a7-429b2e43fb93 https://www.quora.com/How-do-you-insert-images-into-a-LibreOffice-Writer-document LibreOffice Writer
111 ecc2413d-8a48-416e-a3a2-d30106ca36cb https://www.quora.com/How-can-I-insert-a-blank-page-on-libreoffice LibreOffice Writer
112 0e47de2a-32e0-456c-a366-8c607ef7a9d2 https://ask.libreoffice.org/t/how-to-start-page-numbering-on-a-certain-page/39931/4 LibreOffice Writer
113 4bcb1253-a636-4df4-8cb0-a35c04dfef31 https://www.libreofficehelp.com/save-export-writer-documents-in-pdf-epub-format/ LibreOffice Writer
114 0810415c-bde4-4443-9047-d5f70165a697 https://www.youtube.com/watch?v=Q_AaL6ljudU LibreOffice Writer
115 e528b65e-1107-4b8c-8988-490e4fece599 https://www.youtube.com/watch?v=l25Evu4ohKg LibreOffice Writer
116 66399b0d-8fda-4618-95c4-bfc6191617e9 https://www.youtube.com/watch?v=l25Evu4ohKg LibreOffice Writer
117 936321ce-5236-426a-9a20-e0e3c5dc536f https://www.youtube.com/watch?v=l25Evu4ohKg LibreOffice Writer
118 663876c7-3471-43db-ba51-f410b13d9d7d https://askubuntu.com/questions/319593/how-to-type-science-equations-in-libre-office LibreOffice Writer
119 3ef2b351-8a84-4ff2-8724-d86eae9b842e https://askubuntu.com/questions/1066351/how-do-you-center-align-in-libreoffice#:~:text=Ctrl%20%2B%20e%20will%20Center%20align%20the%20cursor%20for%20you. LibreOffice Writer
120 45d61a06-6545-4422-97b7-bc76cfa964c1 https://stackoverflow.com/questions/71685737/how-to-replace-all-newlines-with-paragraph-marks-in-libreoffice-write LibreOffice Writer
121 0b17a146-2934-46c7-8727-73ff6b6483e8 https://askubuntu.com/questions/245695/how-do-you-insert-subscripts-and-superscripts-into-ordinary-non-formula-text-i LibreOffice Writer
122 0e763496-b6bb-4508-a427-fad0b6c3e195 https://ask.libreoffice.org/t/how-do-i-change-the-font-for-the-whole-document-in-writer/9220 LibreOffice Writer
123 f178a4a9-d090-4b56-bc4c-4b72a61a035d https://ask.libreoffice.org/t/how-do-i-make-times-new-roman-the-default-font-in-lo/64604 LibreOffice Writer
124 0a0faba3-5580-44df-965d-f562a99b291c https://stackoverflow.com/questions/64528055/how-to-make-part-of-my-sentence-left-aligned-and-rest-as-right-aligned LibreOffice Writer
125 e246f6d8-78d7-44ac-b668-fcf47946cb50 https://ask.libreoffice.org/t/how-to-change-text-size-color-of-italic-font/77712 LibreOffice Writer
126 8472fece-c7dd-4241-8d65-9b3cd1a0b568 https://stackoverflow.com/questions/37259827/libreoffice-writer-how-to-set-different-colors-to-each-letter LibreOffice Writer
127 88fe4b2d-3040-4c70-9a70-546a47764b48 https://stackoverflow.com/questions/56554555/libreoffice-writer-how-to-create-empty-line-space-after-every-period-in-a-par LibreOffice Writer
128 6a33f9b9-0a56-4844-9c3f-96ec3ffb3ba2 https://superuser.com/questions/762500/how-do-i-find-all-highlighted-text-in-libreoffice-writer LibreOffice Writer
129 d53ff5ee-3b1a-431e-b2be-30ed2673079b https://ask.libreoffice.org/t/how-to-convert-all-uppercase-to-lowercase/53341 LibreOffice Writer
130 72b810ef-4156-4d09-8f08-a0cf57e7cefe https://superuser.com/questions/657792/libreoffice-writer-how-to-apply-strikethrough-text-formatting?rq=1 LibreOffice Writer
131 6f81754e-285d-4ce0-b59e-af7edb02d108 https://superuser.com/questions/789473/remove-duplicate-lines-in-libreoffice-openoffice-writer LibreOffice Writer
132 41c621f7-3544-49e1-af8d-dafd0f834f75 https://superuser.com/questions/1668018/how-to-auto-format-lines-in-libre-office-writer LibreOffice Writer
133 b21acd93-60fd-4127-8a43-2f5178f4a830 https://superuser.com/questions/1097199/how-can-i-double-space-a-document-in-libreoffice?rq=1 LibreOffice Writer
134 59f21cfb-0120-4326-b255-a5b827b38967 https://docs.videolan.me/vlc-user/desktop/3.0/en/basic/media.html#playing-a-file VLC player
135 8ba5ae7a-5ae5-4eab-9fcc-5dd4fe3abf89 https://docs.videolan.me/vlc-user/desktop/3.0/en/basic/recording/playing.html#choose-your-recordings-folder VLC player
136 8f080098-ddb1-424c-b438-4e96e5e4786e https://medium.com/@jetscribe_ai/how-to-extract-mp3-audio-from-videos-using-vlc-media-player-beeef644ebfb VLC player
137 bba3381f-b5eb-4439-bd9e-80c22218d5a7 https://www.quora.com/How-do-I-play-online-videos-using-the-VLC-media-player VLC player
138 a1c3ab35-02de-4999-a7ed-2fd12c972c6e https://www.quora.com/How-do-I-compress-a-video-with-VLC VLC player
139 fba2c100-79e8-42df-ae74-b592418d54f4 https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s VLC player
140 d70666e4-7348-42c7-a06a-664094c5df3c https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s VLC player
141 efcf0d81-0835-4880-b2fd-d866e8bc2294 https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s, https://help.ubuntu.com/stable/ubuntu-help/look-background.html.en VLC player
142 8d9fd4e2-6fdb-46b0-b9b9-02f06495c62f https://www.youtube.com/watch?v=XHprwDJ0-fU&t=436s VLC player
143 aa4b5023-aef6-4ed9-bdc9-705f59ab9ad6 https://videoconverter.wondershare.com/vlc/how-to-rotate-a-video-using-vlc.html?gad_source=1&gclid=CjwKCAiA-vOsBhAAEiwAIWR0TaGSOLkYiBeVQGZSyfeUP3g-tIvYxffl5RFIu0-zrUL1IF41eCw1JRoCnCMQAvD_BwE VLC player
144 386dbd0e-0241-4a0a-b6a2-6704fba26b1c https://superuser.com/questions/1708415/pause-and-play-vlc-in-background?rq=1 VLC player
145 9195653c-f4aa-453d-aa95-787f6ccfaae9 https://superuser.com/questions/1513285/how-can-i-increase-the-maximum-volume-output-by-vlc?rq=1 VLC player
146 5ac2891a-eacd-4954-b339-98abba077adb https://superuser.com/questions/1412810/how-to-prevent-vlc-media-player-from-auto-closing-after-video-end#:%7E:text=Click%20on%20%22Media%22on%20the,VLC%20player%20after%20video%20ending VLC player
147 0d95d28a-9587-433b-a805-1fbe5467d598 https://superuser.com/questions/1299036/vlc-how-to-open-the-folder-of-the-current-playing-video?noredirect=1&lq=1 VLC player
148 d06f0d4d-2cd5-4ede-8de9-598629438c6e https://superuser.com/questions/1039392/changing-colour-of-vlc-volume-slider VLC player
149 a5bbbcd5-b398-4c91-83d4-55e1e31bbb81 https://superuser.com/questions/776056/how-to-hide-bottom-toolbar-in-vlc VLC player
150 f3977615-2b45-4ac5-8bba-80c17dbe2a37 https://www.reddit.com/r/Fedora/comments/rhljzd/how_to_run_multiple_instances_of_vlc_media_player/ VLC player
151 c669a35f-d45a-450e-b1f2-f473748337bb https://www.quora.com/How-do-I-fast-forward-a-video-in-VLC-player VLC player
152 d1ba14d0-fef8-4026-8418-5b581dc68ca0 https://superuser.com/questions/306154/how-to-use-a-b-repeat-feature-of-vlc VLC player
153 215dfd39-f493-4bc3-a027-8a97d72c61bf https://superuser.com/questions/1224784/how-to-change-vlcs-splash-screen VLC player
154 bb5e4c0d-f964-439c-97b6-bdb9747de3f4 https://www.wikihow.com/Remove-an-Email-Account-from-Thunderbird ThunderBird
155 7b6c7e24-c58a-49fc-a5bb-d57b80e5b4c3 https://www.wikihow.com/Access-Gmail-With-Mozilla-Thunderbird ThunderBird
156 b188fe10-ae67-4db8-a154-26a0b8ff8f1e https://www.reddit.com/r/Thunderbird/comments/17vv2os/restore_readability_in_message_list_pane/ ThunderBird
157 12086550-11c0-466b-b367-1d9e75b3910e https://www.bitrecover.com/blog/manage-thunderbird-profiles/ ThunderBird
158 06fe7178-4491-4589-810f-2e2bc9502122 https://www.quora.com/How-do-I-backup-email-files-in-Mozilla-Thunderbird ThunderBird
159 6766f2b8-8a72-417f-a9e5-56fcaa735837 https://www.adsigner.com/user-manual/signatures/setup-email-client-thunderbird/#:~:text=is%20probably%20hidden.-,Right%20click%20on%20the%20empty%20space%20at%20the%20top%20of,signature%20from%20a%20file%20instead. ThunderBird
160 e1e75309-3ddb-4d09-92ec-de869c928143 https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters ThunderBird
161 3d1682a7-0fb0-49ae-a4dc-a73afd2d06d5 https://support.mozilla.org/en-US/kb/organize-your-messages-using-filters ThunderBird
162 35253b65-1c19-4304-8aa4-6884b8218fc0 https://support.mozilla.org/en-US/questions/1259354 ThunderBird
163 d088f539-cab4-4f9a-ac92-9999fc3a656e https://support.mozilla.org/en-US/kb/how-use-attachments ThunderBird
164 2ad9387a-65d8-4e33-ad5b-7580065a27ca https://support.mozilla.org/bm/questions/1027435, https://www.wikihow.tech/Create-Folders-in-Mozilla-Thunderbird ThunderBird
165 480bcfea-d68f-4aaa-a0a9-2589ef319381 https://www.reddit.com/r/Thunderbird/comments/182dg5p/unified_inbox_howto/ ThunderBird
166 37b9808f-b2b4-4177-ab00-9ddfae4bad27 https://www.quora.com/How-can-I-schedule-Mozilla-Thunderbird-to-turn-off-automatically ThunderBird
167 af630914-714e-4a24-a7bb-f9af687d3b91 https://stackoverflow.com/questions/11333148/adding-a-toolbar-button-to-a-thundebird-compose-message-window?rq=3 ThunderBird
168 3299584d-8f11-4457-bf4c-ce98f7600250 https://superuser.com/questions/1643561/would-like-to-see-the-email-address-from-sender-in-the-column ThunderBird
169 030eeff7-b492-4218-b312-701ec99ee0cc https://superuser.com/questions/1781004/how-do-i-remove-the-indentation-and-character-in-quoted-text-of-a-reply-mess ThunderBird
170 94760984-3ff5-41ee-8347-cf1af709fea0 https://superuser.com/questions/1757333/how-can-i-view-thunderbird-in-full-dark-mode ThunderBird
171 99146c54-4f37-4ab8-9327-5f3291665e1e https://superuser.com/questions/1764409/how-to-send-email-with-thunderbird-without-configuring-an-incoming-email-service ThunderBird
172 9656a811-9b5b-4ddf-99c7-5117bcef0626 https://superuser.com/questions/205240/is-there-a-way-to-get-a-popup-confirmation-box-when-you-send-an-email-in-thunder?rq=1 ThunderBird
173 c9e7eaf2-b1a1-4efc-a982-721972fa9f02 https://superuser.com/questions/544480/how-to-apply-automatic-message-filters-to-subfolders-too?noredirect=1&lq=1 ThunderBird
174 bb5e4c0d-f964-439c-97b6-bdb9747de3f4 https://support.google.com/chrome/answer/95426?sjid=16867045591165135686-AP Chrome
175 7b6c7e24-c58a-49fc-a5bb-d57b80e5b4c3 https://support.google.com/chrome/answer/95647?hl=en&ref_topic=7438325&sjid=16867045591165135686-AP#zippy=%2Cdelete-cookies-from-a-site Chrome
176 12086550-11c0-466b-b367-1d9e75b3910e https://www.quora.com/What-are-the-cool-tricks-to-use-Google-Chrome Chrome
177 06fe7178-4491-4589-810f-2e2bc9502122 https://www.wikihow.com/Switch-Tabs-in-Chrome Chrome
178 6766f2b8-8a72-417f-a9e5-56fcaa735837 https://support.google.com/chrome/thread/205881926/it-s-possible-to-load-unpacked-extension-automatically-in-chrome?hl=en Chrome
179 e1e75309-3ddb-4d09-92ec-de869c928143 https://in5stepstutorials.com/google-chrome/save-web-page-as-pdf-in-chrome.php Chrome
180 3d1682a7-0fb0-49ae-a4dc-a73afd2d06d5 https://in5stepstutorials.com/google-chrome/add-change-delete-autofill-address.php Chrome
181 35253b65-1c19-4304-8aa4-6884b8218fc0 https://www.laptopmag.com/articles/how-to-create-desktop-shortcuts-for-web-pages-using-chrome, https://www.reddit.com/r/chrome/comments/13xcbap/crete_shortcut_option_missing/ Chrome
182 d088f539-cab4-4f9a-ac92-9999fc3a656e https://medium.com/@inkverseuk2/useful-tips-and-tricks-for-the-google-chrome-browser-ac7d0d24b3cc Chrome
183 2ad9387a-65d8-4e33-ad5b-7580065a27ca https://www.youtube.com/watch?v=IN-Eq_UripQ Chrome
184 7a5a7856-f1b6-42a4-ade9-1ca81ca0f263 https://www.youtube.com/watch?v=ZaZ8GcTxjXA Chrome
185 3720f614-37fd-4d04-8a6b-76f54f8c222d https://superuser.com/questions/984668/change-interface-language-of-chrome-to-english Chrome
186 b63059a2-53bc-4163-a89f-3ac948c74081 https://superuser.com/questions/1303418/how-do-i-make-chrome-block-absolutely-all-pop-ups?rq=1 Chrome
187 44ee5668-ecd5-4366-a6ce-c1c9b8d4e938 https://superuser.com/questions/1787991/clear-browsing-history-from-specific-site-on-chrome Chrome
188 b5ebc8c6-6329-4373-85b4-9421c97375e9 https://superuser.com/questions/364470/is-there-a-way-to-view-google-chrome-browsing-history-past-three-months-ago?rq=1 Chrome
189 93eabf48-6a27-4cb6-b963-7d5fe1e0d3a9 https://superuser.com/questions/1417973/how-to-disable-google-chrome-dark-mode Chrome
190 2ae9ba84-3a0d-4d4c-8338-3a1478dc5fe3 https://superuser.com/questions/1393683/how-to-change-the-username-in-google-chrome-profiles?rq=1 Chrome
191 480bcfea-d68f-4aaa-a0a9-2589ef319381 https://bugartisan.medium.com/disable-the-new-chrome-ui-round-in-2023-db168271f71e Chrome
192 37b9808f-b2b4-4177-ab00-9ddfae4bad27 https://www.reddit.com/r/chrome/comments/17niw3h/tutorial_how_to_disable_the_download_bubble_in/ Chrome
193 af630914-714e-4a24-a7bb-f9af687d3b91 https://www.howtogeek.com/680260/how-to-change-chromes-default-text-size/ Chrome
194 ae78f875-5b98-4907-bbb5-9c737fc68c03 https://support.google.com/chrome/thread/219988391/increase-search-results-per-page?hl=en Chrome
195 0ed39f63-6049-43d4-ba4d-5fa2fe04a951 https://www.quora.com/How-do-you-find-and-replace-text-in-Visual-Studio-Code VS Code
196 b421106e-b282-4c41-af72-37c95493f95f https://stackoverflow.com/questions/74153883/launch-vscode-with-new-txt-file VS Code
197 53ad5833-3455-407b-bbc6-45b4c79ab8fb https://www.youtube.com/watch?v=VqCgcpAypFQ VS Code
198 eabc805a-bfcf-4460-b250-ac92135819f6 https://www.youtube.com/watch?v=VqCgcpAypFQ VS Code
199 3486f395-ad68-459c-8c39-ea07de934dd4 https://www.youtube.com/watch?v=VqCgcpAypFQ VS Code
200 982d12a5-beab-424f-8d38-d2a48429e511 https://www.youtube.com/watch?v=ORrELERGIHs VS Code
201 4e60007a-f5be-4bfc-9723-c39affa0a6d3 https://campbell-muscle-lab.github.io/howtos_Python/pages/documentation/best_practices/vscode_docstring_extension/vscode_docstring_extension.html#:~:text=Type%2C%20Ctrl%20%2B%20Shift%20%2B%20P,select%20the%20NumPy%20docstring%20format. VS Code
202 e2b5e914-ffe1-44d2-8e92-58f8c5d92bb2 https://superuser.com/questions/1386061/how-to-suppress-some-python-errors-warnings-in-vs-code VS Code
203 9439a27b-18ae-42d8-9778-5f68f891805e https://stackoverflow.com/questions/75832474/how-to-keep-cursor-in-debug-console-when-debugging-in-visual-studio-code VS Code
204 ae506c68-352c-4094-9caa-ee9d42052317 https://superuser.com/questions/1460404/get-visual-studio-code-terminal-history?rq=1 VS Code
205 ea98c5d7-3cf9-4f9b-8ad3-366b58e0fcae https://superuser.com/questions/1748097/vs-code-disable-tree-view-find-explorer-search VS Code
206 c714dcee-cad3-4e12-8f3c-12bdcfcdb048 https://superuser.com/questions/1417361/how-to-disable-file-filtering-in-vs-code-sidebar-explorer?rq=1 VS Code
207 930fdb3b-11a8-46fe-9bac-577332e2640e https://superuser.com/questions/1270103/how-to-switch-the-cursor-between-terminal-and-code-in-vscode VS Code
208 276cc624-87ea-4f08-ab93-f770e3790175 https://www.quora.com/unanswered/How-do-you-set-the-line-length-in-Visual-Studio-Code VS Code
209 9d425400-e9b2-4424-9a4b-d4c7abac4140 https://superuser.com/questions/1466771/is-there-a-way-to-make-editor-tabs-stack-in-vs-code VS Code
210 7a4deb26-d57d-4ea9-9a73-630f66a7b568 https://www.quora.com/How-do-I-edit-a-photo-in-GIMP GIMP
211 554785e9-4523-4e7a-b8e1-8016f565f56a https://www.quora.com/How-do-I-edit-a-photo-in-GIMP GIMP
212 77b8ab4d-994f-43ac-8930-8ca087d7c4b4 https://superuser.com/questions/1636113/how-to-get-gimp-to-recognize-images-or-pictures-folder-as-the-default-folder-for GIMP
213 f4aec372-4fb0-4df5-a52b-79e0e2a5d6ce https://superuser.com/questions/612338/how-do-i-select-and-move-an-object-in-gimp GIMP
214 d52d6308-ec58-42b7-a2c9-de80e4837b2b https://superuser.com/questions/1447106/how-to-get-rid-of-the-gimp-tool-options-box GIMP
215 2a729ded-3296-423d-aec4-7dd55ed5fbb3 https://www.youtube.com/watch?v=lOzSiOIipSM GIMP
216 b148e375-fe0b-4bec-90e7-38632b0d73c2 https://www.quora.com/How-do-I-add-layers-in-GIMP GIMP
217 a746add2-cab0-4740-ac36-c3769d9bfb46 https://www.youtube.com/watch?v=_L_MMU22bAw GIMP
218 7b7617bd-57cc-468e-9c91-40c4ec2bcb3d https://www.youtube.com/watch?v=G_PjQAy0iiU GIMP
219 d16c99dc-2a1e-46f2-b350-d97c86c85c15 https://stackoverflow.com/questions/75185543/use-gimp-to-resize-image-in-one-layer-only GIMP
220 573f79b5-abfe-4507-b455-251d45fe6198 https://stackoverflow.com/questions/45196895/gimp-add-padding-to-multiple-images GIMP
221 06ca5602-62ca-47f6-ad4f-da151cde54cc https://stackoverflow.com/questions/74664666/how-to-export-palette-based-png-in-gimp GIMP
222 fa9b1e10-4d2d-4a13-af76-7efa822b6a8b https://stackoverflow.com/questions/24626608/how-to-combine-several-png-images-as-layers-in-a-single-xcf-image GIMP
223 6b2b72ed-3a10-4849-876a-750f7cdf3886 https://stackoverflow.com/questions/21018007/resize-image-to-fit-canvas-gimp GIMP
224 d0e42fd2-d290-46b3-b598-a6e2b7be9c85 https://stackoverflow.com/questions/56758689/stop-gimp-from-merging-layers-when-de-selecting GIMP
225 e2dd0213-26db-4349-abe5-d5667bfd725c https://superuser.com/questions/839650/how-to-move-an-inserted-text-box-in-gimp GIMP
226 f723c744-e62c-4ae6-98d1-750d3cd7d79d https://www.reddit.com/r/GIMP/comments/12e57w8/how_to_use_gimp_to_exaggerate_contrast/ GIMP
227 8d6b1c9c-1aab-47fe-9ba5-e84c838d0c57 https://www.quora.com/How-can-email-attachments-be-converted-into-a-word-document-using-Mozilla-Thunderbird multiple
228 11e1e614-9696-4d94-88c9-8e556880d41a https://ifttt.com/applets/L2A89geP-send-chrome-software-update-release-alerts-to-email multiple
229 57956154-f0fe-486b-88b8-e7126da035a9 https://zapier.com/apps/email/integrations/google-sheets/547/get-email-notifications-for-new-rows-in-a-google-sheets-spreadsheet multiple
230 ec14c524-b245-456d-abd6-ec12c746e9f8 https://zapier.com/apps/gmail/integrations/google-sheets/2618/save-new-gmail-emails-matching-certain-traits-to-a-google-spreadsheet multiple
231 cbf5fbda-425e-4619-bcf2-0ea8d4c0bfa3 https://zapier.com/apps/google-sheets/integrations/google-slides/13919/refresh-charts-on-a-google-slides-presentation-when-rows-are-updated-on-google-sheets multiple
232 a54284d0-7b93-4327-bfcc-3a421516dbdd https://superuser.com/questions/655622/cannot-drag-images-from-thunderbird-to-word multiple
233 58565672-7bfe-48ab-b828-db349231de6b https://superuser.com/questions/1792660/open-link-from-other-application-does-not-open-the-url-in-firefox multiple
234 6d72aad6-187a-4392-a4c4-ed87269c51cf https://superuser.com/questions/923171/converting-openoffice-impress-presentation-to-video-without-screen-recording multiple
235 937087b6-f668-4ba6-9110-60682ee33441 https://superuser.com/questions/187440/set-default-ubuntu-video-player-as-vlc multiple
236 f8cfa149-d1c1-4215-8dac-4a0932bad3c2 https://superuser.com/questions/1803088/libreoffice-calc-clears-clipboard multiple
237 5e974913-6905-4c3f-8b65-d7837f3931cc https://stackoverflow.com/questions/61856141/how-can-i-start-thunderbird-and-minimize-the-window-on-startup-in-ubuntu multiple
238 7c179dad-f1c7-4892-b53f-d1c4023d23c7 https://stackoverflow.com/questions/21155085/pasting-excel-tables-in-thunderbird-e-mail-client multiple
239 4a68b2dd-70f2-4532-9bc1-d21878bd8cb2 https://stackoverflow.com/questions/65669955/thunderbird-how-to-send-a-mail-to-all-receivers-of-a-folder multiple
240 c8457fde-b14b-4aba-b402-144842ea29e1 https://stackoverflow.com/questions/65788200/how-to-open-xlsx-files-in-ms-excel-from-vs-code multiple
241 81c425f5-78f3-4771-afd6-3d2973825947 https://www.zyxware.com/articles/3770/how-to-transfer-data-in-libreoffice-calc-to-libreoffice-writer-in-table-format multiple
242 bb83cab4-e5c7-42c7-a67b-e46068032b86 https://ask.libreoffice.org/t/save-impress-presentation-as-writer-document/5291/4 multiple
243 227d2f97-562b-4ccb-ae47-a5ec9e142fbb https://discourse.gnome.org/t/gimp-and-libre-office-writer/15430/4 multiple
244 a6bbc08c-51e9-4ee4-9327-83d05075d960 https://forum.openoffice.org/en/forum/viewtopic.php?t=105055 multiple
245 964e6e03-ba31-466b-8c15-5a351a81f675 https://www.maketecheasier.com/mail-merge-thunderbird-calc/ multiple
246 2fe4b718-3bd7-46ec-bdce-b184f5653624 https://www.thewindowsclub.com/how-to-create-animated-gif-from-a-video-file-using-vlc-and-gimp multiple
247 d02b9364-6bb0-4c7e-9dbd-4db62822bc26 https://stackoverflow.com/questions/38306910/simple-python-script-to-get-a-libreoffice-base-field-and-play-on-vlc multiple
248 57fb469b-127a-46fa-8281-bbb3840efdf5 https://support.mozilla.org/en-US/questions/1150626 multiple
249 3680a5ee-6870-426a-a997-eba929a0d25c https://unix.stackexchange.com/questions/510850/how-to-open-calc-from-terminal-and-insert-files multiple
250 2d8c8a20-6f54-4c2e-ad56-61fbe7af6b78 https://www.quora.com/How-do-I-force-LibreOffice-Calc-to-recalculate-a-spreadsheet-from-the-command-line multiple
251 ee9a3c83-f437-4879-8918-be5efbb9fac7 https://stackoverflow.com/questions/64589140/convert-ods-to-csv-using-command-line-when-libreoffice-instance-is-running multiple
252 f7dfbef3-7697-431c-883a-db8583a4e4f9 https://www.thegeekdiary.com/libreoffice-command-examples-in-linux/ multiple
253 2b9493d7-49b8-493a-a71b-56cd1f4d6908 https://devicetests.com/kill-libreoffice-writer-command-line-ubuntu multiple
254 51f5801c-18b3-4f25-b0c3-02f85507a078 https://github.com/danielrcollins1/ImpressExtractNotes multiple
255 81de345e-5473-4cb6-a74d-b6abf3475a6a https://stackoverflow.com/questions/45588952/how-can-i-compose-and-send-email-in-thunderbird-from-commandline multiple
256 2c9fc0de-3ee7-45e1-a5df-c86206ad78b5 https://nikki-ricks.medium.com/how-to-use-git-add-commit-and-push-in-vs-code-and-command-line-35c0e8c47b62 multiple
257 510f64c8-9bcc-4be1-8d30-638705850618 https://www.geeksforgeeks.org/how-to-start-vs-code-from-the-terminal-command-line/ multiple
258 9ff484f7-5c09-4398-ae29-d5904e59e138 https://stackoverflow.com/questions/38606973/playing-opening-and-pausing-vlc-command-line-executed-from-python-scripts multiple
259 d9b7c649-c975-4f53-88f5-940b29c47247 https://marketplace.uipath.com/listings/extract-the-first-1000-gmail-emails-from-the-current-month-in-a-new-google-sheets-report multiple
260 be4ef0dc-0f70-4936-81d8-3cd2b04482f8 https://marketplace.uipath.com/listings/table-data-extraction-for-sales-opportunities-to-excel-workbook multiple
261 78aed49a-a710-4321-a793-b611a7c5b56b https://marketplace.uipath.com/listings/upload-email-attachments-from-gmail-to-google-drive multiple
262 897e3b53-5d4d-444b-85cb-2cdc8a97d903 https://marketplace.uipath.com/listings/convert-word-file-to-pdf-and-store-in-onedrive multiple
263 4e9f0faf-2ecc-4ae8-a804-28c9a75d1ddc https://marketplace.uipath.com/listings/extract-data-from-a-new-invoice-file-in-google-drive-and-store-it-in-google-sheets4473 multiple
264 b52b40a5-ad70-4c53-b5b0-5650a8387052 https://marketplace.uipath.com/listings/merge-pdfs-from-gmail-email-attachments-and-upload-to-gogle-drive multiple
265 46407397-a7d5-4c6b-92c6-dbe038b1457b https://marketplace.uipath.com/listings/upload-to-google-drive-images-from-pdf-attachments-received-via-gmail multiple
266 a0b9dc9c-fc07-4a88-8c5d-5e3ecad91bcb https://marketplace.uipath.com/listings/backup-important-emails-to-onedrive-or-sharepoint multiple
267 665f4af1-617d-4009-baff-84ff66071e6a https://www.howtogeek.com/663927/how-to-open-google-chrome-using-command-prompt-on-windows-10/#open-chrome-straight-to-a-specific-website multiple
268 e6313b30-3903-4ed9-8c7d-4c47bf51fc96 https://stackoverflow.com/questions/12258086/how-do-i-run-google-chrome-as-root multiple

View File

@@ -1,238 +0,0 @@
import csv
import os
import yt_dlp
from docx import Document
import requests
from bs4 import BeautifulSoup
from PIL import Image
import pytesseract
from io import BytesIO
from docx import Document
import re
import markdownify
from markdownify import markdownify as md
def valid_xml_char_ordinal(c):
codepoint = ord(c)
# conditions ordered by presumed frequency
return (
0x20 <= codepoint <= 0xD7FF or
codepoint in (0x9, 0xA, 0xD) or
0xE000 <= codepoint <= 0xFFFD or
0x10000 <= codepoint <= 0x10FFFF
)
def download_and_clean_youtube_subtitles(video_url, txt_filepath):
# set up youtube-dl options to download the subtitles
subtitles_path = txt_filepath[0:-4]
ydl_opts = {
'skip_download': True,
'writesubtitles': True,
'writeautomaticsub': True, # if no subtitles are available, try to generate them
'subtitleslangs': ['en'],
'outtmpl': f'{subtitles_path}.%(ext)s',
'quiet': True,
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
# download the subtitles
ydl.download([video_url])
subtitle_file = f'{subtitles_path}.en.vtt'
# read the subtitle file
subtitles = []
try:
with open(subtitle_file, 'r', encoding='utf-8') as file:
lines = file.readlines()
# define a pattern to match the time line
pattern = re.compile(r'(\d{2}:\d{2}:\d{2}.\d{3} --> \d{2}:\d{2}:\d{2}.\d{3})|(^WEBVTT)|(^Kind: captions)|(^Language: .*)')
# clean the subtitles
for line in lines:
# if this line is a time line or it is blank , skip it
if pattern.match(line) or line.strip() == '':
continue
# add this subtitle line to subtitles list, remove the trailing spaces and line change
subtitles.append(line.strip())
# remove duplicated subtitles
subtitles = list(dict.fromkeys(subtitles))
# save the subtitles as a txt file
with open(txt_filepath, 'w', encoding='utf-8') as f:
for line in subtitles:
if line:
f.write(line + '\n')
except IOError:
print(f"Could not read file: {subtitle_file}")
# scrape a webpage and perform OCR on images
def scrape_and_ocr_forum(url, doc):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
text_elements = soup.find_all(['h1', 'h2', 'h3', 'p', 'li'])
for element in text_elements:
doc.add_paragraph(element.get_text())
image_elements = soup.find_all('img')
for image in image_elements:
if 'src' not in image.attrs:
continue
image_url = image['src']
if image_url.startswith('http'):
if not image_url.endswith('.svg') and not image_url.endswith('.png'):
continue
if 'neveragain.allstatics.com/2019/assets/icon/logo' in image_url:
continue
img_response = requests.get(image_url, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text != ' ' and ocr_text != '':
cleaned_string = ''.join(c for c in ocr_text if valid_xml_char_ordinal(c))
doc.add_paragraph(cleaned_string)
def superuser_to_markdown(url, doc_filepath):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# set up the markdown document
markdown_content = ""
# get the question title and body
question_title = soup.find('h1').get_text(strip=True)
question = soup.find('div', {'id': 'question'})
if question:
question_body = question.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += f"# {question_title}\n\n" + markdownify.markdownify(question_body, heading_style="ATX") + "\n\n"
# get all answers
answers = soup.find_all('div', {'class': 'answer'})
for answer in answers:
answer_body = answer.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += markdownify.markdownify(answer_body, heading_style="ATX") + "\n\n"
# deal with images and perform OCR
all_img_tags = question.find_all('img') + [img for answer in answers for img in answer.find_all('img')]
for img_tag in all_img_tags:
image_src = img_tag.get('src') or img_tag.get('data-src') # Superuser uses lazy loading
if image_src and image_src.startswith('http'):
img_response = requests.get(image_src, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text.strip(): # if the OCR result is not empty, add it to the markdown content
markdown_content += "```\n" + ocr_text.strip() + "\n```\n\n"
with open(doc_filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
def stack_overflow_to_markdown(url, doc_filepath):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# set up the markdown document
markdown_content = ""
# get the question title and body
question = soup.find('div', {'id': 'question'})
question_title = soup.find('h1').get_text(strip=True)
if question:
question_body = question.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += f"# {question_title}\n\n" + markdownify.markdownify(question_body, heading_style="ATX") + "\n\n"
# get all answers
answers = soup.find_all('div', {'class': 'answer'})
for answer in answers:
answer_body = answer.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += markdownify.markdownify(answer_body, heading_style="ATX") + "\n\n"
# deal with images and perform OCR
all_img_tags = soup.find_all('img')
for img_tag in all_img_tags:
image_url = img_tag['src']
if image_url.startswith('http') and (image_url.endswith('.svg') or image_url.endswith('.png')): # 确保图片URL有效
img_response = requests.get(image_url, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text.strip():
markdown_content += "```\n" + ocr_text.strip() + "\n```\n\n"
with open(doc_filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
def scrape_webpage_to_markdown(url, doc_filepath):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
articles = soup.find_all('article') or soup.find_all('main') or soup.find_all('div', {'class': 'lia-message-body-content'})
if not articles:
return
markdown_content = ''
# scrape the webpage and perform OCR on images
for article in articles:
for child in article.recursiveChildGenerator():
# if this is an image, perform OCR
if child.name == 'img':
img_url = child.get('src')
if not img_url.startswith(('http:', 'https:')):
img_url = '{}{}'.format(url, img_url)
if not img_url.endswith('.svg') and not img_url.endswith('.png'):
continue
if 'neveragain.allstatics.com/2019/assets/icon/logo' in img_url:
continue
try:
img_response = requests.get(img_url, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text.strip():
markdown_content += '\n```plaintext\n{}\n```\n'.format(ocr_text.strip())
continue
except PIL.UnidentifiedImageError:
print("unidentified image")
# Not an image, so continue recursively calling function
if child.name is None:
continue
html_str = str(child)
markdown_content += md(html_str) + '\n\n'
with open(doc_filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
# process a URL and save the file
def process_url(url, doc_id, app):
doc_filepath = f"/content/drive/MyDrive/SourceDoc/{doc_id}_{app}.md"
txt_filepath = f"/content/drive/MyDrive/SourceDoc/{doc_id}_{app}.txt"
doc = Document()
if 'youtube.com' in url or 'youtu.be' in url:
download_and_clean_youtube_subtitles(url, txt_filepath)
elif 'superuser.com' in url:
superuser_to_markdown(url, doc_filepath)
elif 'stackoverflow.com' in url:
stack_overflow_to_markdown(url, doc_filepath)
else:
scrape_webpage_to_markdown(url, doc_filepath)
# read the CSV file and process each URL
csv_filepath = './Get_Source_Doc - Sheet1.csv'
with open(csv_filepath, 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
cnt = 55
for row in reader:
if cnt>0:
cnt -= 1
continue
process_url(row['Source'], row['id'], row['InvolvedApp'])
print(row)

View File

@@ -1,293 +0,0 @@
import csv
import os
import io
import fitz
import yt_dlp
from docx import Document
import requests
from bs4 import BeautifulSoup
from PIL import Image
import pytesseract
from io import BytesIO
from docx import Document
import re
import markdownify
from markdownify import markdownify as md
def download_pdf(url):
response = requests.get(url)
response.raise_for_status() # 确保请求是成功的
return io.BytesIO(response.content)
def pdf_to_markdown(pdf_stream, markdown_path):
document = fitz.open(stream=pdf_stream, filetype="pdf")
markdown_content = ""
for page_number in range(len(document)):
page = document[page_number]
text = page.get_text()
markdown_content += text + "\n\n"
# 提取图片并添加到 Markdown 文件。图片被保存在同一目录下
image_list = page.get_images(full=True)
if image_list:
markdown_content += f"### Page {page_number + 1} Images\n"
for img_index, image in enumerate(image_list, start=1):
# 提取图片
xref = image[0]
base64_image = document.extract_image(xref)
image_bytes = base64_image["image"]
# 写入图片到磁盘
image_filename = f"output_image_page_{page_number + 1}_{img_index}.png"
image_abs_path = os.path.join(os.path.dirname(markdown_path), image_filename)
with open(image_abs_path, "wb") as image_file:
image_file.write(image_bytes)
# 在 Markdown 文件中添加图片引用
markdown_content += f"![Page {page_number + 1} Image {img_index}]({image_filename})\n\n"
with open(markdown_path, "w", encoding="utf-8") as md_file:
md_file.write(markdown_content)
document.close()
def valid_xml_char_ordinal(c):
codepoint = ord(c)
# conditions ordered by presumed frequency
return (
0x20 <= codepoint <= 0xD7FF or
codepoint in (0x9, 0xA, 0xD) or
0xE000 <= codepoint <= 0xFFFD or
0x10000 <= codepoint <= 0x10FFFF
)
def download_and_clean_youtube_subtitles(video_url, txt_filepath):
# 设置yt-dlp库的选项来下载字幕
subtitles_path = txt_filepath[0:-4]
ydl_opts = {
'skip_download': True,
'writesubtitles': True,
'writeautomaticsub': True, # 如果视频没有字幕,尝试下载自动生成的字幕
'subtitleslangs': ['en'], # 下载英文字幕
'outtmpl': f'{subtitles_path}.%(ext)s', # 确保保存到可写目录
'quiet': True,
}
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
# 获取视频信息,下载字幕文件
ydl.download([video_url])
subtitle_file = f'{subtitles_path}.en.vtt'
# 读取下载的字幕文件
subtitles = []
try:
with open(subtitle_file, 'r', encoding='utf-8') as file:
# 读取所有行
lines = file.readlines()
# 正则表达式匹配时间戳和其他不相关的标记
pattern = re.compile(r'(\d+:\d\d:\d\d.\d+ --> \d+:\d\d:\d\d.\d+)|(\s*<[^>]+>)')
# 去除时间戳和HTML标签等只保留字幕文本
lines = [re.sub(pattern, '', line).strip() for line in lines if line.strip() and not pattern.match(line)]
# 清洗字幕
for line in lines:
# 如果这是一个时间线或者其他不需要的信息,跳过它
if pattern.match(line) or line.strip() == '':
continue
# 添加到字幕列表,同时去除愈加和前导空白符
subtitles.append(line.strip())
# 去除可能的重复行
subtitles = list(dict.fromkeys(subtitles))
# 保存至txt文件
with open(txt_filepath, 'w', encoding='utf-8') as f:
for line in subtitles:
if line: # 避免写入空行
f.write(line + '\n')
except IOError:
print(f"Could not read file: {subtitle_file}")
# 爬取论坛内容对图片进行OCR处理并保存为.docx文件
def scrape_and_ocr_forum(url, doc):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
text_elements = soup.find_all(['h1', 'h2', 'h3', 'p', 'li'])
for element in text_elements:
doc.add_paragraph(element.get_text())
image_elements = soup.find_all('img')
for image in image_elements:
if 'src' not in image.attrs:
continue
image_url = image['src']
if image_url.startswith('http'):
if not image_url.endswith('.svg') and not image_url.endswith('.png'):
continue
if 'neveragain.allstatics.com/2019/assets/icon/logo' in image_url:
continue
img_response = requests.get(image_url, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text != ' ' and ocr_text != '':
cleaned_string = ''.join(c for c in ocr_text if valid_xml_char_ordinal(c))
doc.add_paragraph(cleaned_string)
def superuser_to_markdown(url, doc_filepath):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 创建Markdown文件的内容
markdown_content = ""
# 获取问题标题和内容
question_title = soup.find('h1').get_text(strip=True)
question = soup.find('div', {'id': 'question'})
if question:
question_body = question.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += f"# {question_title}\n\n" + markdownify.markdownify(question_body, heading_style="ATX") + "\n\n"
# 获取所有回答
answers = soup.find_all('div', {'class': 'answer'})
for answer in answers:
answer_body = answer.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += markdownify.markdownify(answer_body, heading_style="ATX") + "\n\n"
# 处理图片并执行OCR
all_img_tags = question.find_all('img') + [img for answer in answers for img in answer.find_all('img')]
for img_tag in all_img_tags:
image_src = img_tag.get('src') or img_tag.get('data-src') # Superuser使用延迟加载的图片
if image_src and image_src.startswith('http'):
img_response = requests.get(image_src, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text.strip(): # 如果OCR结果非空则添加到Markdown内容中
markdown_content += "```\n" + ocr_text.strip() + "\n```\n\n"
# 将Markdown内容写入文件
with open(doc_filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
def stack_overflow_to_markdown(url, doc_filepath):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 创建Markdown文件的内容
markdown_content = ""
# 获取问题标题和内容
question = soup.find('div', {'id': 'question'})
question_title = soup.find('h1').get_text(strip=True)
if question:
question_body = question.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += f"# {question_title}\n\n" + markdownify.markdownify(question_body, heading_style="ATX") + "\n\n"
# 获取所有回答
answers = soup.find_all('div', {'class': 'answer'})
for answer in answers:
answer_body = answer.find('div', {'class': 's-prose js-post-body'}).prettify()
markdown_content += markdownify.markdownify(answer_body, heading_style="ATX") + "\n\n"
# 处理图片并执行OCR
all_img_tags = soup.find_all('img')
for img_tag in all_img_tags:
image_url = img_tag['src']
if image_url.startswith('http') and (image_url.endswith('.svg') or image_url.endswith('.png')): # 确保图片URL有效
img_response = requests.get(image_url, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text.strip(): # 如果OCR结果非空则添加到Markdown内容中
markdown_content += "```\n" + ocr_text.strip() + "\n```\n\n"
# 将Markdown内容写入文件
with open(doc_filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
def scrape_webpage_to_markdown(url, doc_filepath):
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
# 假设文章内容在 HTML 的 'article' 标签中,根据实际页面结构调整
articles = soup.find_all('article') or soup.find_all('main') or soup.find_all('div', {'id':'steps'}, {'class':'section_text'}) # 或其他包含主要内容的HTML标签
if not articles:
articles = soup.find_all('div', {'class': 'lia-message-body-content'})
markdown_content = ''
# 抓取所有图文信息
for article in articles:
for child in article.recursiveChildGenerator():
# 如果是图片则进行OCR
if child.name == 'img':
img_url = child.get('src')
if not img_url:
continue
if not img_url.startswith(('http:', 'https:')):
img_url = '{}{}'.format(url, img_url)
if not img_url.endswith('.svg') and not img_url.endswith('.png'):
continue
if 'neveragain.allstatics.com/2019/assets/icon/logo' in img_url:
continue
print(img_url)
try:
img_response = requests.get(img_url, stream=True)
img = Image.open(BytesIO(img_response.content))
ocr_text = pytesseract.image_to_string(img)
if ocr_text.strip():
markdown_content += '\n```plaintext\n{}\n```\n'.format(ocr_text.strip())
continue
except PIL.UnidentifiedImageError:
print("unidentified image")
# 不是标签可能是NavigableString或其他
if child.name is None:
continue
# 抓取标签并转换为Markdown
html_str = str(child)
markdown_content += md(html_str) + '\n\n'
# 写入markdown文件
with open(doc_filepath, 'w', encoding='utf-8') as f:
f.write(markdown_content)
# 处理单个URL
def process_url(url, doc_id, app):
doc_filepath = f"/content/drive/MyDrive/SourceDoc/{doc_id}_{app}.md"
txt_filepath = f"/content/drive/MyDrive/SourceDoc/{doc_id}_{app}.txt"
doc = Document()
if 'youtube.com' in url or 'youtu.be' in url:
download_and_clean_youtube_subtitles(url, txt_filepath)
elif url.endswith('.pdf'):
pdf_stream = download_pdf(url)
pdf_to_markdown(pdf_stream, doc_filepath)
elif 'superuser.com' in url or 'askubuntu.com' in url:
superuser_to_markdown(url, doc_filepath)
elif 'stackoverflow.com' in url:
stack_overflow_to_markdown(url, doc_filepath)
else:
scrape_webpage_to_markdown(url, doc_filepath)
# 读取CSV文件中的数据并执行对应操作
csv_filepath = '/content/Get_Source_Doc - Sheet1.csv' # 更新为你的CSV文件实际路径
with open(csv_filepath, 'r', newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile)
cnt = 176
for row in reader:
if cnt>0:
cnt -= 1
continue
process_url(row['Source'], row['id'], row['InvolvedApp'])
print(row)

View File

@@ -1,17 +0,0 @@
import requests
import json
url = "https://tiktok-download-video1.p.rapidapi.com/feedSearch"
querystring = {"keywords":"Ubuntu desktop","count":"10","cursor":"0","region":"US","publish_time":"0","sort_type":"1"}
headers = {
"X-RapidAPI-Key": "YOUR_API_KEY",
"X-RapidAPI-Host": "tiktok-download-video1.p.rapidapi.com"
}
response = requests.get(url, headers=headers, params=querystring)
print(response.json())
with open("./record_1.json", "w") as f:
json.dump(response.json(), f)

View File

@@ -1,506 +0,0 @@
{
"code": 0,
"msg": "success",
"processed_time": 1.2181,
"data": {
"videos": [
{
"aweme_id": "v0f025gc0000cfdgkhbc77ufdvjieor0",
"video_id": "7195358717750070555",
"region": "ID",
"title": "#CapCut comparing the pros and cons of two operating system: #windows and #linux. \ud83d\udc68\u200d\ud83d\udcbb Unleash the power of #Linux ! Experience a better, more efficient computing with this open-source OS #windows11 #windows10 #ubuntu #programming #computerscience #opensource #technology #FaktaProgrammer #jagocoding #debian #malware #hacking #ProgrammerImut ",
"cover": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-p-0037-aiso/2410a4ce346f409ca1f0ba4b543ce7c3_1675300016~tplv-dmt-logom:tos-useast2a-pv-0037-aiso/77578d1e8c9a4efaaa057636e35ab262.image?x-expires=1703127600&x-signature=9GzGgxD2brvooV5TsmsuyCFqloU%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-p-0037-aiso/5904cc8b48a14d4081f05e97dd006328_1675300016~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=zKuLeet7txU5bAPZCeWTFRYHZas%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 15,
"play": "https://v16m.tiktokcdn-us.com/385a61f83cddd3276b6b3955ae059c98/6582ae05/video/tos/useast2a/tos-useast2a-pve-0037-aiso/oIYbF3pDWeVcQUPIUB8jADjnQ2PNBDBLbw2Cne/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1398&bt=699&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=NDQzaDw1N2Q8OTpoNzNkPEBpM3JseWk6ZmtqaTMzZjgzM0BjM2EtXzRgNjIxXjJeNWJhYSNvYmdhcjRfaGFgLS1kL2Nzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/f6c45472d69d11105cd4f55ebb8e7d13/6582ae05/video/tos/useast2a/tos-useast2a-pve-0037c001-aiso/oI2pBQPnjBbeYpn8DBFwAAI3CDcbb27QeVUKnF/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1124&bt=562&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=11&rc=ZzVlODZnZWdmM2k2OzhmZ0BpM3JseWk6ZmtqaTMzZjgzM0AtX2BfLjJgX2AxYGJjNDQzYSNvYmdhcjRfaGFgLS1kL2Nzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16-ies-music.tiktokcdn.com/obj/ies-music-aiso/7195358744048438042.mp3",
"music_info": {
"id": "7195358701144902426",
"title": "original sound - ferryops_",
"play": "https://sf16-ies-music.tiktokcdn.com/obj/ies-music-aiso/7195358744048438042.mp3",
"cover": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-avt-0068-giso/5b59cd09101f0a570efe722f5f1f64b1~c5_1080x1080.jpeg?x-expires=1703127600&x-signature=w1qF6e5dmhhCgWPwiDvSJxZVQO4%3D",
"author": "ferry",
"original": true,
"duration": 15,
"album": ""
},
"play_count": 814198,
"digg_count": 55739,
"comment_count": 1876,
"share_count": 1911,
"download_count": 62,
"create_time": 1675300014,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6924124906000303105",
"unique_id": "ferryops_",
"nickname": "ferry",
"avatar": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-avt-0068-giso/5b59cd09101f0a570efe722f5f1f64b1~c5_300x300.jpeg?x-expires=1703127600&x-signature=NNsWWsjrvJ206kY8qyFxiZE5k20%3D"
},
"is_top": 0
},
{
"aweme_id": "v12044gd0000chd8vdbc77uea2obsidg",
"video_id": "7231251211062758702",
"region": "US",
"title": "What would you do with this data? #computervision #machinelearning #objectdetection #csproject #softwareengineer ",
"cover": "https://p16-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/ee1c7307d8ba46008d9a2f1002ffe99b_1683656884~tplv-dmt-logom:tos-useast5-i-0068-tx/5f1c1ee9247449aa8d86b36beeacc10d.image?x-expires=1703127600&x-signature=Wzp2xq0jwoPBoDrSEDydKP8RitY%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p19-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/c5b40f31562a4b1c9bc6e9066b8da76c_1683656884~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=q301jDESVmXKzurDSZEsAaY71u4%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 126,
"play": "https://v16m.tiktokcdn-us.com/dd179aa8851feda2a2f84f6859d626ce/6582ae74/video/tos/useast5/tos-useast5-pve-0068-tx/osaeSLPIjUoAMkRbctIQWFnIjDbeDH1RCACekt/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1490&bt=745&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=Ojg4OGZnPDtlZzY0Ojk6NEBpamxlNWg6Zmc7azMzZzczNEAxYV5iMy1gXjIxY2ExNi0yYSNhcGxecjRfc2FgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00010000",
"wmplay": "https://v16m.tiktokcdn-us.com/b36feb41d71b86ed6e4e6ea7a72e71af/6582ae74/video/tos/useast5/tos-useast5-pve-0068-tx/oAIHCeIo1WkngCFIA1kYRbDfeIAjagtcq28oYQ/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1548&bt=774&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=Mzw7Zjs2NjY1MzxpNTc3aEBpamxlNWg6Zmc7azMzZzczNEBfYy40XzBeNWAxMWEuNF5gYSNhcGxecjRfc2FgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00010000",
"music": "https://sf19.tiktokcdn-us.com/obj/ies-music-tx/7231251227135281962.mp3",
"music_info": {
"id": "7231251193572477742",
"title": "original sound - codingai",
"play": "https://sf19.tiktokcdn-us.com/obj/ies-music-tx/7231251227135281962.mp3",
"cover": "https://p16-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/69600b7c44fc05a3b118277409c5c6fb~c5_1080x1080.jpeg?x-expires=1703127600&x-signature=eg%2B7HmT9JXLgeMm0WgzQHu9nh2I%3D",
"author": "Eric",
"original": true,
"duration": 126,
"album": ""
},
"play_count": 277284,
"digg_count": 20971,
"comment_count": 188,
"share_count": 868,
"download_count": 221,
"create_time": 1683656883,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "7044388915265668143",
"unique_id": "codingai",
"nickname": "Eric",
"avatar": "https://p16-sign.tiktokcdn-us.com/tos-useast8-avt-0068-tx2/69600b7c44fc05a3b118277409c5c6fb~c5_300x300.jpeg?x-expires=1703127600&x-signature=2n0cRjUEqT4lHZcZkoKH0wSURVY%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000c9g4kbrc77u91sdh9jp0",
"video_id": "7088747410289102086",
"region": "IT",
"title": "Come installare #ubuntu e far risorgere un vecchio pc #aletech",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/e25e3d586f4c4cdfa18235f07b686497_1650477660~tplv-dmt-logom:tos-useast2a-v-0068/85ca53bad5e4402ba107aa9f88f3d396.image?x-expires=1703127600&x-signature=D18vkekhPxb8FvOOLcFLUcx9xLA%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/41390a6f86074b92b6f2c0e0f7862940_1650477670~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=jTNGQhpF1J2xAkQt9Y99KyBUK%2Fs%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 42,
"play": "https://v16m.tiktokcdn-us.com/2911fa4f722b77bde13d550ed592bd72/6582ae20/video/tos/useast2a/tos-useast2a-ve-0068c003/386472d4c6fa4b479b2cf07c829bf268/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=3076&bt=1538&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=NDVlPDc0ZDNkZjo7ZGRnaUBpM21rdjw6ZmU3PDMzNzczM0AwMF5jNi0yNV4xNDJiXzAyYSNtNmEucjRvaGRgLS1kMTZzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/9cc6a5d30e0c8948fa294f0027bd0c53/6582ae20/video/tos/useast2a/tos-useast2a-ve-0068c003/9262ec5e631d49e399d3a4bec28db2a7/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=3068&bt=1534&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=NTxmOmVoO2g0aDk3ZzlkZkBpM21rdjw6ZmU3PDMzNzczM0A0NDU1XzUuNi4xX15gYDQuYSNtNmEucjRvaGRgLS1kMTZzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/38acb76cefbb49a187e366d26cf62dcc",
"music_info": {
"id": "6756231813640751105",
"title": "Better Days",
"play": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/38acb76cefbb49a187e366d26cf62dcc",
"cover": "https://p16-sg.tiktokcdn.com/aweme/720x720/tos-alisg-v-2774/f2bad9596ac24f3a891c8fd1d5f1ac14.jpeg",
"author": "",
"original": false,
"duration": 60,
"album": "Better Days"
},
"play_count": 96398,
"digg_count": 6714,
"comment_count": 221,
"share_count": 378,
"download_count": 771,
"create_time": 1650477624,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6903482507896587266",
"unique_id": "ale_tech_",
"nickname": "Ale_tech",
"avatar": "https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/81f0a65e38808852ad043323d2ce9f1f~c5_300x300.jpeg?x-expires=1703127600&x-signature=djzLzF0pH%2BAV9a8qJvTZh8WNYJE%3D"
},
"is_top": 0
},
{
"aweme_id": "v07025g50000c1ld595r2810d6r02sr0",
"video_id": "6947597057498680578",
"region": "ID",
"title": "Reply to @efryday1 segini aja ya, klo full sampe instalasi ga cukup \ud83d\ude01 #linux #ubuntu #fyp",
"cover": "https://p16-sign-sg.tiktokcdn.com/tos-alisg-p-0037/64ad02f4cfed4bd6961c1c1c992f7df1_1617613505~tplv-dmt-logom:tos-alisg-i-0000/d375b8ca573c48e18f7f19175091a0a2.image?x-expires=1703127600&x-signature=GcUS%2Bet8IeNtkQKFSCTILJMULwU%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign-sg.tiktokcdn.com/tos-alisg-p-0037/f3fb7b0dc7aa4337bcfd1badd15b403e_1617613505~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=Zea7B3dtoIkndr3j5gE0ehRiM6g%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 31,
"play": "https://v16m.tiktokcdn-us.com/a46680841f4e969f7c489dd568c85b63/6582ae15/video/tos/alisg/tos-alisg-pve-0037/efc3dc88570e4b408f460da5b30fb8cf/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=2154&bt=1077&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=N2lpaGg2ODpmZDM7aGZkOkBpM3YzOTM7dTxnNDMzODgzM0A0Yl9fNDQvXl8xLTEzMS4vYSNvL29hLi8yMmlgLS1kLzRzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/6ec40d75d2efc39bbbc62d727e37dcb5/6582ae15/video/tos/alisg/tos-alisg-pve-0037/a773953f390642158983d23034e27b84/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=2146&bt=1073&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=MzNnOGk2PDMzaDQ2Nzg8ZUBpM3YzOTM7dTxnNDMzODgzM0AuMTIxMF42Xl4xYl8tYV9fYSNvL29hLi8yMmlgLS1kLzRzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/o4DXDrZtQBCbzoc9djRgk49nQBelNUnnqBesLO",
"music_info": {
"id": "6936177291449862145",
"title": "Terpesona",
"play": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/o4DXDrZtQBCbzoc9djRgk49nQBelNUnnqBesLO",
"cover": "https://p16-sg.tiktokcdn.com/aweme/720x720/tos-alisg-v-2774/3c59e86071a6488386f0eb8d0520c80e.jpeg",
"author": "",
"original": false,
"duration": 60,
"album": "Terpesona"
},
"play_count": 90199,
"digg_count": 5316,
"comment_count": 138,
"share_count": 56,
"download_count": 329,
"create_time": 1617613504,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6568018206484742146",
"unique_id": "nvmbrxi",
"nickname": "adit, iya pasaran iya",
"avatar": "https://p16-sign-sg.tiktokcdn.com/tos-alisg-avt-0068/468629c8128b024d5787e670f9b42cf5~c5_300x300.jpeg?x-expires=1703127600&x-signature=t7lOKDBIC5r4n%2BalT1G8j4jKHGQ%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000ciktif3c77ub4lij07ag",
"video_id": "7253570500482321669",
"region": "DO",
"title": "If you love coding leave your \u2764\ufe0f #softwareengineer #softwaredeveloper #focus #fullstackdeveloper #ubuntudesktop #ubuntu #cybersecurity #reactnativedeveloper #androiddev #androiddeveloper #frontenddeveloper credits: mobiledevpro \ud83d\ude4f",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/5290f82af0a041f4ae3482161633c5ec_1688853494?x-expires=1703127600&x-signature=Qp1zu10vuLK%2BNq%2FcoElwf7hDO%2Bo%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/4c4a0d1a522c47e9bdd2b4e033cba110_1688853493~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=zy%2BADnksas488G1HYiROxwdXsKo%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 11,
"play": "https://v16m.tiktokcdn-us.com/84404bbc3b0d32ee0baea347f3a1d0ef/6582ae01/video/tos/useast2a/tos-useast2a-ve-0068c001/ocfAhU8g7ZJ81dITBenAQkqsRlkQtB9EPdDTbX/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1368&bt=684&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=NjlpOzxlMzhoOjgzOThpZEBpajptb2U6Zml3bDMzNzczM0BiYC9jYjMuNjIxM2IwMy4yYSNeLWYxcjQwZmhgLS1kMTZzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/a2d5770f1c2b3957e6394ba7426f6d67/6582ae01/video/tos/maliva/tos-maliva-ve-0068c801-us/o4JUKZ6bhM7pCAKIC4rnZCAeej5fUS2y1gmPJH/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1418&bt=709&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=NTw4Ojk2NWlkODtkaGU4ZEBpajptb2U6Zml3bDMzNzczM0BjYjZgXi5hXzIxMC9fL2AuYSNeLWYxcjQwZmhgLS1kMTZzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16-ies-music.tiktokcdn.com/obj/ies-music-aiso/7232735770502859546.mp3",
"music_info": {
"id": "7232735763421596442",
"title": "All my Life Lil Durk DrillyEditz",
"play": "https://sf16-ies-music.tiktokcdn.com/obj/ies-music-aiso/7232735770502859546.mp3",
"cover": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-avt-0068-euttp/b05fa4d33296c39c75fbc760a3f3ec5c~c5_1080x1080.jpeg?x-expires=1703127600&x-signature=8MeRalgtFOdb9QfxLhB2QcnIToo%3D",
"author": "DrillyEditz\ud83e\udd77\ud83c\udffd",
"original": true,
"duration": 16,
"album": ""
},
"play_count": 35581,
"digg_count": 2212,
"comment_count": 76,
"share_count": 26,
"download_count": 3,
"create_time": 1688853492,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "7150316965491721221",
"unique_id": "systemf4iled",
"nickname": "System F4iled",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/742fa96d7edbfd240757b83abf1dee0b~c5_300x300.jpeg?x-expires=1703127600&x-signature=q8rwCWfCZfWurxF6cfYOaSFciNo%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000cbsv2tjc77uftkprfpdg",
"video_id": "7131996966136958213",
"region": "TH",
"title": "Linux > Windows as always #Windows #Windows10 #Linux #Ubuntu #UbuntuMATE #computer #fyp",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/421b9598296b4bc6923c82eeb0f74104_1660547458~tplv-dmt-logom:tos-useast2a-v-0068/ab4d5c65921f4556be5bd4218a05e684.image?x-expires=1703127600&x-signature=mKiZ6hytGR6zx7ek4ORgtryE6w8%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/e8f1878fc8ba466aa5af013169e33e84_1660547459~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=6L2yZY%2FL03UOop%2FV7q7SX1Q64hI%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 15,
"play": "https://v19.tiktokcdn-us.com/edc39bdef7b4266e334ae233f724aeb6/6582ae05/video/tos/useast2a/tos-useast2a-pve-0068/4d8f2b0e1f2b4f60ad84a60fa124bfc3/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=3178&bt=1589&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=NWk6O2hkaDdkM2g7ZTg6PEBpanN1bmk6Znd5ZTMzNzczM0AyYl9eLTReXzYxXzYvLTI0YSNhY21xcjRnL3BgLS1kMTZzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v19.tiktokcdn-us.com/c882763d2ef55a77003b1dace8fd7fd1/6582ae05/video/tos/maliva/tos-maliva-ve-0068c801-us/512ba1d0e8824c9087d6aea78ffa3a6b/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=3388&bt=1694&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=Ojc5NGk7aTdnM2RkOjQ2ZkBpanN1bmk6Znd5ZTMzNzczM0AtXmJhYC5fXy0xXzItYzRhYSNhY21xcjRnL3BgLS1kMTZzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/ocvaqFeexInKSUDFFPAAbfDlG4UPzTODg5VBEC",
"music_info": {
"id": "6915348665175526145",
"title": "Can You Feel My Heart",
"play": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/ocvaqFeexInKSUDFFPAAbfDlG4UPzTODg5VBEC",
"cover": "https://p16-sg.tiktokcdn.com/aweme/720x720/tos-alisg-v-2774/b7c28602318840fbbb4f4b0f2ed7ddf9.jpeg",
"author": "",
"original": false,
"duration": 15,
"album": "Can You Feel My Heart"
},
"play_count": 36974,
"digg_count": 1078,
"comment_count": 202,
"share_count": 23,
"download_count": 3,
"create_time": 1660547455,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6988352212003243009",
"unique_id": "hannor_smith",
"nickname": "han.flac \ud83c\udf1f\ud83c\udfa7\ud83c\udfcd\ufe0f",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/58167255ee1d05d70dffc59ec0286e96~c5_300x300.jpeg?x-expires=1703127600&x-signature=N3KkHMBaqDBqVcHCt833OonyJ58%3D"
},
"is_top": 0
},
{
"aweme_id": "v12044gd0000cb4rr83c77u2coev35og",
"video_id": "7118429570973519150",
"region": "US",
"title": "If you haven't tried Linux yet, Ubuntu should be your first \ud83e\udd79\ud83d\udcbb #linuxdistro #ubuntulinux #oldlaptopmotherboard #oldpchardware #linux",
"cover": "https://p19-sign.tiktokcdn-us.com/obj/tos-useast5-p-0068-tx/57a059b3776f4deeaa4a7297dd9d46fa_1657388545?x-expires=1703127600&x-signature=2HaAe082pCt55gBKb9YvXCyITyw%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/8680ac0cc03840df9ff6f003cbeb74f6_1657388545~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=s3Xz2qsI2um65ZUbw3Lg8SQYo20%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 30,
"play": "https://v19.tiktokcdn-us.com/607a59a261b518e59c26873e2d17f22d/6582ae13/video/tos/useast5/tos-useast5-pve-0068-tx/948fbacccb394ae2b722a1e39f3daa59/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1524&bt=762&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=aDY4PDw5OjM1ZWlkNDxpaUBpajh5cjU6Zjt1ZTMzZzczNEAzXi4tYl4uNi0xLjBeNC5hYSNsMGJgcjQwbzFgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v19.tiktokcdn-us.com/eee0d5c470e85e78957dc78605caf792/6582ae13/video/tos/useast5/tos-useast5-ve-0068c001-tx/27add3d74a14413091513d4c7a3bd553/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1522&bt=761&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=aDppOTdmPDY2OzszaDtnOkBpajh5cjU6Zjt1ZTMzZzczNEBgL2IzNDFhNWAxNWFgYTU1YSNsMGJgcjQwbzFgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/oc1hI8e1jwQ9aPyoBOnCUc6YZwjgZBbt1GDfbY",
"music_info": {
"id": "6778968637492430849",
"title": "Blue Blood",
"play": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/oc1hI8e1jwQ9aPyoBOnCUc6YZwjgZBbt1GDfbY",
"cover": "https://p16-sg.tiktokcdn.com/aweme/720x720/tos-alisg-v-2774/c24e133f8d134031b03a673aa747ed6d.jpeg",
"author": "",
"original": false,
"duration": 60,
"album": "It's Always Sunny In Philadelphia (Music from the Original FX Series)"
},
"play_count": 30464,
"digg_count": 817,
"comment_count": 29,
"share_count": 34,
"download_count": 84,
"create_time": 1657388542,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "7113859000824316974",
"unique_id": "buggintech",
"nickname": "buggintech",
"avatar": "https://p16-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/e390a937f6bc4281817b391361497762~c5_300x300.jpeg?x-expires=1703127600&x-signature=nyeyvxtxVn%2F0SE%2Fn7Wnavk3wGjE%3D"
},
"is_top": 0
},
{
"aweme_id": "v12044gd0000cgi7l53c77u11maehifg",
"video_id": "7216028231185616171",
"region": "US",
"title": "Replying to @fltlnsb I say all this with extreme confidence, as I\u2019ve spent the last 12 years supporting users ages 30-70. People that grew up with computers around, some who have used computers for 20 years. Telling someone \u2018you need to learn an entire new platform and convert your PDF\u2019s with command line because it\u2019s better\u2019 is ridiculous. Can YOU do it faster with CLI? Yes. Does that mean everybody should? Absolutely not. Here in 2023, the vast majority of people in the work force and ones who own business are barely getting by with the Windows computers they have. Microsoft has a chokehold on the end user facing side of business/corporate/enterprise business. Uprooting their infrastructure to implement a product that will change everything they do from a day to day because \u2018it\u2019s better\u2019 - sorry, not a business expense anyone is willing to swallow. You can spend 15 hours a week for a few weeks learning the OS and figuring out whats good about it. Other people do not. Time is money. and is business, just because you csn - doesnt mean you should. #ubuntu #linux #computers #naaackers ",
"cover": "https://p16-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/0485fb4c1f2549c8987ba323ed26993f_1680112511~tplv-dmt-logom:tos-useast5-i-0068-tx/798594786eff41458cbbc4f6da8a1476.image?x-expires=1703127600&x-signature=ZARZhRKsQwA%2FgqGM4p6Y%2BD%2F%2FRpI%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/aff34ca418e1453390f96584faae5535_1680112510~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=qiKmXCjMnnE%2B8P68jaEydOsTtEU%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 58,
"play": "https://v19.tiktokcdn-us.com/ac39a5443137abb7743118c8e6c38046/6582ae30/video/tos/useast5/tos-useast5-ve-0068c002-tx/126f8a804a18420cb9f9a0362aa3ac6c/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1760&bt=880&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=Mzk6NGc7Zzg3NDs2O2Q4OkBpamxocDQ6Zjg6ajMzZzczNEAxNC8wMC1hNmAxLjYwXzI2YSNjZV4ucjQwaWZgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v19.tiktokcdn-us.com/d9bb3ef4e9ef24d612514d12c451b6cc/6582ae30/video/tos/useast5/tos-useast5-ve-0068c004-tx/f40dd86127a2452fa9b021f295880c2c/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1862&bt=931&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=O2g0aTM1Zjw1NWk7OTZkaEBpamxocDQ6Zjg6ajMzZzczNEBeNTJjNWJfXl4xNDZeYTBfYSNjZV4ucjQwaWZgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16.tiktokcdn-us.com/obj/ies-music-tx/7216028260373662507.mp3",
"music_info": {
"id": "7216028213967997739",
"title": "original sound - naaackers",
"play": "https://sf16.tiktokcdn-us.com/obj/ies-music-tx/7216028260373662507.mp3",
"cover": "https://p19-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/99794bd713d80b1c2b65aff94b0e6500~c5_1080x1080.jpeg?x-expires=1703127600&x-signature=a6w1ZerLtyqMcKa2H0ioqXBy%2FxQ%3D",
"author": "Naaackers",
"original": true,
"duration": 58,
"album": ""
},
"play_count": 7621,
"digg_count": 528,
"comment_count": 227,
"share_count": 5,
"download_count": 2,
"create_time": 1680112522,
"anchors": [
{
"actions": [
{
"action_type": 1,
"icon": {
"height": 720,
"uri": "tiktok-obj/28px_primary_create_onDark3x.png",
"url_list": [
"https://p16-sg.tiktokcdn.com/obj/tiktok-obj/28px_primary_create_onDark3x.png?biz_tag=anchor.effect"
],
"url_prefix": null,
"width": 720
},
"schema": "shoot"
}
],
"component_key": "anchor_effect",
"description": "Effects",
"extra": "{\"effect_source\":0,\"is_commerce\":0}",
"icon": {
"height": 720,
"uri": "tiktok-obj/20px_anchor_effect3x.png",
"url_list": [
"https://p16-sg.tiktokcdn.com/obj/tiktok-obj/20px_anchor_effect3x.png?biz_tag=anchor.effect"
],
"url_prefix": null,
"width": 720
},
"id": "454747",
"keyword": "Green Screen Video",
"log_extra": "{\"anchor_id\":\"454747\",\"anchor_name\":\"Green Screen Video\",\"anchor_type\":\"prop\"}",
"thumbnail": {
"height": 64,
"uri": "d846c3603d36559c76691965ba808340",
"url_list": [
"https://lf16-effectcdn-va.tiktokcdn.com/obj/ies-fe-effect-va/d846c3603d36559c76691965ba808340",
"https://lf21-effectcdn-va.tiktokcdn.com/obj/ies-fe-effect-va/d846c3603d36559c76691965ba808340",
"https://lf19-effectcdn-va.tiktokcdn.com/obj/ies-fe-effect-va/d846c3603d36559c76691965ba808340"
],
"url_prefix": null,
"width": 64
},
"type": 28
}
],
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6757790857447539718",
"unique_id": "naaackers",
"nickname": "Naaackers",
"avatar": "https://p19-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/99794bd713d80b1c2b65aff94b0e6500~c5_300x300.jpeg?x-expires=1703127600&x-signature=f7mkopk%2F2EG%2FpA98qcgATY8nj80%3D"
},
"is_top": 0
},
{
"aweme_id": "v0f025gc0000cfaidr3c77u090l3co8g",
"video_id": "7193698776148725019",
"region": "TH",
"title": "Life of a Linux user \ud83d\udc27 #linux #ubuntu #computer #laptop #tech #techtok ",
"cover": "https://p16-sign-useast2a.tiktokcdn.com/obj/tos-useast2a-p-0037-aiso/6fb0705918f0413b9127aa0c2c95c0ed_1674913526?x-expires=1703127600&x-signature=yNngPeJxRl5AB6rIiA3EjO%2BO6Gg%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-p-0037-aiso/908c47399ad2445b8720a5c0c49e45fa_1674913529~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=yt9L2hrWPZ3Z1mbX9tVT8KDOeB0%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 15,
"play": "https://v19.tiktokcdn-us.com/3e418870739bcd9b1a1244bfa89d4b8f/6582ae05/video/tos/useast2a/tos-useast2a-pve-0037-aiso/oMRKA6h7oCSVjVnvBCN2JToIzNA9fhQY2AIxpU/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=2328&bt=1164&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=aGYzNDs5ZDlnNzhmOjk8NEBpanI2MzM6ZnVsaTMzZjgzM0AvMDM0LzQxXjExMGFhNTIyYSM1YGk2cjQwYV5gLS1kL2Nzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v19.tiktokcdn-us.com/1e5ce0481d836bbef971d1c12ebefd60/6582ae05/video/tos/useast2a/tos-useast2a-pve-0037-aiso/o43NInhzZSNh2AoQixpVBYRUbCf2CKA6o2A6Wo/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=2616&bt=1308&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=ZTQ1OjRlOTc5NDg5OzRmPEBpanI2MzM6ZnVsaTMzZjgzM0A2MDE2MGJhNmAxMy8uLzYtYSM1YGk2cjQwYV5gLS1kL2Nzcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/oYnmdQz4MBF51IDQzbZptpTBBaALqgveOLC1ek",
"music_info": {
"id": "6969850109240559617",
"title": "Meow",
"play": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/oYnmdQz4MBF51IDQzbZptpTBBaALqgveOLC1ek",
"cover": "https://p16-sg.tiktokcdn.com/aweme/720x720/tos-alisg-v-2774/df24a43905f9413bb3596cb8c765bc16.jpeg",
"author": "",
"original": false,
"duration": 60,
"album": "Meow"
},
"play_count": 29000,
"digg_count": 458,
"comment_count": 31,
"share_count": 9,
"download_count": 1,
"create_time": 1674913523,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6988352212003243009",
"unique_id": "hannor_smith",
"nickname": "han.flac \ud83c\udf1f\ud83c\udfa7\ud83c\udfcd\ufe0f",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/58167255ee1d05d70dffc59ec0286e96~c5_300x300.jpeg?x-expires=1703127600&x-signature=N3KkHMBaqDBqVcHCt833OonyJ58%3D"
},
"is_top": 0
},
{
"aweme_id": "v12044gd0000c9hnderc77u0gkpj1f80",
"video_id": "7089641605862313262",
"region": "US",
"title": "#linux #sysadmin #systemadministrator #python #fyp\u30b7 #ubuntu #tech #computerscience #networkengineer #linux #bash",
"cover": "https://p16-sign.tiktokcdn-us.com/obj/tos-useast5-p-0068-tx/f4004afdbfb1457fa72e54aeebbae658_1650685820?x-expires=1703127600&x-signature=baO3nkbdG73H%2FLlG%2BB%2B5E7Nff3k%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=2023122003034909B448A5A66536000675",
"origin_cover": "https://p16-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/8995429c7adb447083dfa93330af88bd_1650685820~tplv-tiktokx-360p.webp?x-expires=1703127600&x-signature=CPnQVAqZ%2F2C8tS%2FmgBczNQzDnmM%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=2023122003034909B448A5A66536000675",
"duration": 47,
"play": "https://v19.tiktokcdn-us.com/0c2c6034ef9b8ebc826a41cd168a3bff/6582ae25/video/tos/useast5/tos-useast5-ve-0068c003-tx/e25fcce499b04eaf97928d4c70f27070/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1502&bt=751&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=M2loZDhkZTMzaDg1OzloOUBpM2ltbjM6ZmhxPDMzZzczNEAvYzEvMDEvXjExLy9gYDQ1YSM1Lm1kcjRvYWVgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"wmplay": "https://v19.tiktokcdn-us.com/540ebc82370825c5bb5cac7605ba9166/6582ae25/video/tos/useast5/tos-useast5-pve-0068-tx/a06e405ea9f042eebc7d7d3432a5a3d3/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1498&bt=749&bti=NTY6QGo0QHM6OjZANDQuYCMucCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZNx0PD1J-wtxg9w8HGM5kEeC~&mime_type=video_mp4&qs=0&rc=aTo4N2QzaDxpaDs2OjRlOkBpM2ltbjM6ZmhxPDMzZzczNEA2MC0vMmAtXmAxMGI2XjZjYSM1Lm1kcjRvYWVgLS1kMS9zcw%3D%3D&l=2023122003034909B448A5A66536000675&btag=e00008000",
"music": "https://sf16.tiktokcdn-us.com/obj/ies-music-tx/7089641612577409835.mp3",
"music_info": {
"id": "7089641579396287278",
"title": "original sound - stevenservo",
"play": "https://sf16.tiktokcdn-us.com/obj/ies-music-tx/7089641612577409835.mp3",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/62713abc4ad5f8eb52869addf6611a92~c5_1080x1080.jpeg?x-expires=1703127600&x-signature=x8ba50BVMtG%2BVOppSeHHwPsi2x8%3D",
"author": "StevenServo",
"original": true,
"duration": 47,
"album": ""
},
"play_count": 4083,
"digg_count": 427,
"comment_count": 28,
"share_count": 18,
"download_count": 44,
"create_time": 1650685819,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6941572883425166342",
"unique_id": "stevenservo",
"nickname": "StevenServo",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/62713abc4ad5f8eb52869addf6611a92~c5_300x300.jpeg?x-expires=1703127600&x-signature=sQFsgOJXOOxGQtHf4cwmfNrSKX4%3D"
},
"is_top": 0
}
],
"cursor": 10,
"hasMore": true
}
}

View File

@@ -1,17 +0,0 @@
import requests
import json
url = "https://tiktok-download-video1.p.rapidapi.com/feedSearch"
querystring = {"keywords":"VS code","count":"10","cursor":"0","region":"US","publish_time":"0","sort_type":"1"}
headers = {
"X-RapidAPI-Key": "YOUR_API_KEY",
"X-RapidAPI-Host": "tiktok-download-video1.p.rapidapi.com"
}
response = requests.get(url, headers=headers, params=querystring)
print(response.json())
with open("./record.json", "w") as f:
json.dump(response.json(), f)

View File

@@ -1,373 +0,0 @@
{
"code": 0,
"msg": "success",
"processed_time": 1.2462,
"data": {
"videos": [
{
"aweme_id": "v09044g40000cdrtb5jc77u48deft16g",
"video_id": "7167433112283008261",
"region": "NL",
"title": "\u201cYou have been misinformed, as much as we\u2019ve been misinformed.\u201d #blackpeople #africancommunity #blackpower #blackunity #panafricanism #fyp #foryou #panafrican #afrikancommunity #blackconsciousness #melanin #africa #blackcommunity #unlearnandrelearn #blackexcellence #problack #knowthyself #ubuntu",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/b9093c120b9944fda3f547001d44a240_1668798075?x-expires=1703124000&x-signature=4%2BExSPK3MmTFdQCMYg72mi5HDzg%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/e124bf8b4c67438b901351498b4b5695_1668798074~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=0bJVu2w0UcX9iAgRQW7h%2F%2F4OYSA%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 40,
"play": "https://v19.tiktokcdn-us.com/cce82f9db7d6c71f833e2b53e2abc39b/6582a3a2/video/tos/useast2a/tos-useast2a-pve-0068/okIE3ejh9BGhBnnpUbp4OJQQD71rNdIWeBWARo/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=2522&bt=1261&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=NGQ1ZTc2aGY5ZTs3PDtoOUBpajRpZzc6Zjh3ZzMzNzczM0A1YDEwXi00Xi0xMjY0YWBgYSMzcWI1cjRnX29gLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"wmplay": "https://v19.tiktokcdn-us.com/0201af034764a80c072969f8d1ebf395/6582a3a2/video/tos/useast2a/tos-useast2a-ve-0068c003/ooYQ9UGW3IjANcl1r8DJBedERBonhQWJnIb9eh/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=2592&bt=1296&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=NTM2ZTZpNjZnNjo7NzxlZUBpajRpZzc6Zjh3ZzMzNzczM0AuNl9fYjYtNS8xLTRjMjIuYSMzcWI1cjRnX29gLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"music": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7167433130218556166.mp3",
"music_info": {
"id": "7167433094969821958",
"title": "original sound - afrikancommunity",
"play": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7167433130218556166.mp3",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_1080x1080.jpeg?x-expires=1703124000&x-signature=kP1cVyhAwezOqb3NoY3PVxO9Oyo%3D",
"author": "afrikancommunity",
"original": true,
"duration": 40,
"album": ""
},
"play_count": 4059853,
"digg_count": 785436,
"comment_count": 5817,
"share_count": 12996,
"download_count": 11150,
"create_time": 1668798067,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6813642741462287365",
"unique_id": "afrikancommunity",
"nickname": "afrikancommunity",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_300x300.jpeg?x-expires=1703124000&x-signature=QIJZsNfd2YOgDg8lMGEqGQeam24%3D"
},
"is_top": 0
},
{
"aweme_id": "v0f025gc0000cglvmnrc77u4ni1u20bg",
"video_id": "7212008888734878982",
"region": "BW",
"title": "S/O @Fiksology\ud83e\udef4 ka DC\ud83d\udd25@gavin.ubuntu @Jame McVernando #ubuntubandmerch #thamiubuntu #SAMA28 ",
"cover": "https://p16-sign-useast2a.tiktokcdn.com/obj/tos-useast2a-p-0037-aiso/29910b3791a7474babf262da0477c5ee_1680604010?x-expires=1703124000&x-signature=96i6RGuz10acj1SwttTl1FwE9YQ%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-p-0037-aiso/71a9299ab7a446d39f99542fefcf521a_1680604009~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=s%2FD6JYmr8UF3GflvYGTwX%2FhlvVE%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 22,
"play": "https://v16m.tiktokcdn-us.com/fbc1b7c9d6df457b01e73329c76b5592/6582a390/video/tos/useast2a/tos-useast2a-pve-0037-aiso/oMAXWfuEQQ8FJFNSeEr89paDofng8LACfAbT3g/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1840&bt=920&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=4&rc=M2dpNjhkZWY0PDhmaTc4Z0BpajN4bDc6ZnF5ajMzZjgzM0AvYjQvMC9fX2AxL2JhX14vYSNfLy5rcjRvamlgLS1kL2Nzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/18d13ec31cad5bffc05a1f795a3769aa/6582a390/video/tos/useast2a/tos-useast2a-pve-0037c001-aiso/o4AgX8Cfar83ne9MWbgEfbJSA8DINxHoAQCfQu/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=4390&bt=2195&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=NjNkMzg8NmhkaWg7NDs6ZEBpajN4bDc6ZnF5ajMzZjgzM0BiXzBfX14zXjMxNDMxMjY1YSNfLy5rcjRvamlgLS1kL2Nzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"music": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7205224029014264582.mp3",
"music_info": {
"id": "7205224038348000005",
"title": "original sound - basiiey_monnapula",
"play": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7205224029014264582.mp3",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/ae049960ea6786673783ce66b36dc7da~c5_1080x1080.jpeg?x-expires=1703124000&x-signature=%2FnY5uAyksD41s%2Bm8ECAFLIAtXfo%3D",
"author": "Basetsana Monnapula",
"original": true,
"duration": 32,
"album": ""
},
"play_count": 6868872,
"digg_count": 673843,
"comment_count": 2832,
"share_count": 8103,
"download_count": 463,
"create_time": 1679176676,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "217487781219024896",
"unique_id": "thami.ubuntu",
"nickname": "Thami Philemon",
"avatar": "https://p16-sign-useast2a.tiktokcdn.com/tos-useast2a-avt-0068-giso/e546ddc5cc70ede037ac5397cd068323~c5_300x300.jpeg?x-expires=1703124000&x-signature=gFNFdUl%2BtBIHAI2sX2ANcjUvqyo%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000cc2hhdbc77ufp0p13l9g",
"video_id": "7135137277650439430",
"region": "NL",
"title": "That that you do most, will be that that you do best #jawanzakunjufu #NBA #blackthinkers #imhotep #blackhistory #blackpeople #africancommunity #blackpower #blackunity #panafricanism #fyp #foryou #panafrican #afrikancommunity #blackconsciousness #blackcommunity #unlearnandrelearn #blackexcellence #problack #knowthyself #ubuntu",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/09d637f654744d62826facb8a685a44f_1661278613?x-expires=1703124000&x-signature=85qRg1ex%2FkscTT8sSfRpq7XSvos%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/bbc3f2523b50459099bec727131b73c0_1661278613~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=PIvHym7TJAU%2BXGScgIuFGaRVkzI%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 60,
"play": "https://v19.tiktokcdn-us.com/1f8f8c36c8e7b1d288c09be54090c378/6582a3b6/video/tos/useast2a/tos-useast2a-ve-0068c002/2a36ec9fd62e44a79fd341682312a92e/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1212&bt=606&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=Zjs1ZjxlNWY8ZzllNTw5ZkBpam80M2k6ZmdrZjMzNzczM0BjNjBfXzA1NWAxLWAxNDMzYSM2MG1tcjRfZS9gLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00010000",
"wmplay": "https://v19.tiktokcdn-us.com/a48c0af8c7cdf127e4c085c61adfbb89/6582a3b6/video/tos/useast2a/tos-useast2a-pve-0068/7d4538584c7e424a9aa60e034d02c6e8/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1254&bt=627&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=NjVkaDxlZ2c0aWllZ2Q1NkBpam80M2k6ZmdrZjMzNzczM0BeLl4uNmA0X2AxMGFfLy80YSM2MG1tcjRfZS9gLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00010000",
"music": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7135137305857460998.mp3",
"music_info": {
"id": "7135137291257154310",
"title": "original sound - afrikancommunity",
"play": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7135137305857460998.mp3",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_1080x1080.jpeg?x-expires=1703124000&x-signature=kP1cVyhAwezOqb3NoY3PVxO9Oyo%3D",
"author": "afrikancommunity",
"original": true,
"duration": 60,
"album": ""
},
"play_count": 3509817,
"digg_count": 406909,
"comment_count": 5287,
"share_count": 27964,
"download_count": 12202,
"create_time": 1661278609,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6813642741462287365",
"unique_id": "afrikancommunity",
"nickname": "afrikancommunity",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_300x300.jpeg?x-expires=1703124000&x-signature=QIJZsNfd2YOgDg8lMGEqGQeam24%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000cbhc463c77u5po59g8fg",
"video_id": "7125471227543670022",
"region": "NL",
"title": "They don\u2019t tell us about ourselves. #blackpeople #africancommunity #blackpower #blackunity #burnaboy #blackhistory #ancientafrica #panafricanism #fyp #foryou #panafrican #afrikancommunity #blackconsciousness #blackcommunity #unlearnandrelearn #blackexcellence #problack #knowthyself #ubuntu",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/27058259ac9c4f7996ed15f7d35fcb42_1659028058?x-expires=1703124000&x-signature=zt3tBpttXmjohAqGGMuQZU0Ef%2FU%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/5b086bdb9aa644448d1219834f894637_1659028057~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=0%2BVWKeBo8T%2FHZ2bfJx7bGxsnNUo%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 43,
"play": "https://v16m.tiktokcdn-us.com/d5828b1ca12fa0904ce987640b5debfc/6582a3a5/video/tos/useast2a/tos-useast2a-ve-0068c003/1dab5ac30d07444fb1115e537e4656fd/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1362&bt=681&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=aDU7aDVpNWdmOGk6NjhoNkBpajs8cjg6ZjlmZTMzNzczM0BeYmEzYi8xXzExYTYvMi1fYSNjZDJtcjQwMWVgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/b8f7853d30e428a6af5bc705ffeb227d/6582a3a5/video/tos/useast2a/tos-useast2a-ve-0068c004/a8726699cd774e08b10c124967f1095c/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1398&bt=699&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=ZzNlM2k0OWg2OGhpNWVkaUBpajs8cjg6ZjlmZTMzNzczM0AyLmEwL2IvXi4xY2MxMTAuYSNjZDJtcjQwMWVgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"music": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7125471236305849094.mp3",
"music_info": {
"id": "7125471221475527429",
"title": "original sound - afrikancommunity",
"play": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7125471236305849094.mp3",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_1080x1080.jpeg?x-expires=1703124000&x-signature=kP1cVyhAwezOqb3NoY3PVxO9Oyo%3D",
"author": "afrikancommunity",
"original": true,
"duration": 43,
"album": ""
},
"play_count": 2663740,
"digg_count": 289424,
"comment_count": 4539,
"share_count": 16995,
"download_count": 62151,
"create_time": 1659028056,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6813642741462287365",
"unique_id": "afrikancommunity",
"nickname": "afrikancommunity",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_300x300.jpeg?x-expires=1703124000&x-signature=QIJZsNfd2YOgDg8lMGEqGQeam24%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000cht15sjc77u6asjve4b0",
"video_id": "7240121196505812229",
"region": "TR",
"title": "#linux #windows #windows10 #windows8 #windows81 #windows7 #windowsvista #windowsxp #microsoft #gnome #macos #apple #arch #ubuntu #comedyvideo #komedi #komik #fyp #kesfet #ke\u015ffet #turkey #turkiye #teknoloji #bili\u015fim #bilisim #pcsystem #2023 #intelcore #bilgisayar #nvidiageforce #gamer #edit #pcbuild #phonk #amdryzen5000series #61 #trabzon ",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/912a019391e84924a0feba2bafc5833c_1685722084?x-expires=1703124000&x-signature=L2s%2BqZmvLKnWjgFn1LIQkRqb61M%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/ee011f41126140cea95ed09e2f928eb9_1685722084~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=xo8psLpjw39%2BJiowhbMq8JT5vNs%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 14,
"play": "https://v16m.tiktokcdn-us.com/6f76e364f63a124e0cecd737216514a4/6582a389/video/tos/useast2a/tos-useast2a-ve-0068c001/o0cgJIJyAXLIhZSIjksCCuf2eDo6Qg80XrGebn/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=3484&bt=1742&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=ZDQzaTdmO2Q1MzppNjxmZEBpMzd5djk6ZnY0azMzNzczM0AwYF9eLmI2Ni0xMjNjLTJjYSNfYmdecjRnMnFgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/8466b29aabc35b2e0d1cae354b5bc489/6582a389/video/tos/useast2a/tos-useast2a-pve-0068/oUr6jIDrepkDIQtuCAUQEMLbyfBgqeInQ3SCWh/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=3566&bt=1783&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=OztpNzQ1aDNoPDtoOjQ8Z0BpMzd5djk6ZnY0azMzNzczM0AyLTEvLzFiNS0xLjFeMzVjYSNfYmdecjRnMnFgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"music": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7240121223304235782.mp3",
"music_info": {
"id": "7240121203456428805",
"title": "original sound - drizzlep6",
"play": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7240121223304235782.mp3",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/251581f4d1594f04ea2f325ff4cc2a07~c5_1080x1080.jpeg?x-expires=1703124000&x-signature=2LG3zWl2%2B7QD8BPwl4NTwXj2bXw%3D",
"author": "Milli G\u00f6r\u00fc\u015f\u00e7\u00fc Volkan \ud83c\udf3f\ud83c\udf41",
"original": true,
"duration": 15,
"album": ""
},
"play_count": 1704069,
"digg_count": 247851,
"comment_count": 29,
"share_count": 40070,
"download_count": 491,
"create_time": 1685722082,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "7214552603395916805",
"unique_id": "drizzlep6",
"nickname": "Milli G\u00f6r\u00fc\u015f\u00e7\u00fc Volkan \ud83c\udf3f\ud83c\udf41",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/251581f4d1594f04ea2f325ff4cc2a07~c5_300x300.jpeg?x-expires=1703124000&x-signature=VNzWdrg82BH2GPcFrY2f5AOs7OQ%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000cghd6ujc77ucrvaksck0",
"video_id": "7215562429403565317",
"region": "AT",
"title": "would be a shame if i forgot to turn of the network #virtualmachine #vm #virtualbox #windows #linux #ubuntu ",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/5fe4d7b7b2524275af1b0e245641ff49_1680004049?x-expires=1703124000&x-signature=xjALXpMVrtWAlD4JQx47n3PLCHw%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/c9d3e9b708164fe0b78d35b47bba445b_1680004049~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=aRETt6Wk39aE1F4zOKWceUGQFKY%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 7,
"play": "https://v16m.tiktokcdn-us.com/23adf16946df423842b6b0ce4eb05d25/6582a381/video/tos/useast2a/tos-useast2a-pve-0068/okLmMJhUIgoy9xEN90fkidIOo9mVqCA3zAWIDM/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=414&bt=207&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=NTtnZWk3ZWU5aTlpZTc5PEBpM2ZueWY6ZnhnajMzNzczM0AzXzFiXzEtXzExYWMuMjM2YSNocF5vcjRnM2VgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"wmplay": "https://v16m.tiktokcdn-us.com/5006f2b9180bc17f23aa2c733bd751a2/6582a381/video/tos/useast2a/tos-useast2a-ve-0068c002/o4NDMgNh4oE9y9ok3UAmIOAaY9IPfVC7zMsW0i/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=442&bt=221&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=NWhlNmdoZTRlZDw0NzVmPEBpM2ZueWY6ZnhnajMzNzczM0A1MjAxMWMzNTAxXjAzXmAuYSNocF5vcjRnM2VgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"music": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/94e9293d28a3496981f09994bdb78107",
"music_info": {
"id": "6855250725862115330",
"title": "Coconut Mall (From \"Mario Kart Wii\")",
"play": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/94e9293d28a3496981f09994bdb78107",
"cover": "https://p16-sg.tiktokcdn.com/aweme/720x720/tos-alisg-v-2774/a8f7d19a20714d9f9e8adc4e69d0708c.jpeg",
"author": "",
"original": false,
"duration": 60,
"album": "Mario Kart Wii, The Themes"
},
"play_count": 1526953,
"digg_count": 194938,
"comment_count": 408,
"share_count": 3334,
"download_count": 748,
"create_time": 1680004048,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6539155051389129743",
"unique_id": "robert_juergerer",
"nickname": "Robert J\u00fcrgerer",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/8a0e92e0a08bbab2c6c25a13a73ddb35~c5_300x300.jpeg?x-expires=1703124000&x-signature=fREAm5jTL1lkhWduDuVUiFZsP9o%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000cbmogv3c77ueej864sc0",
"video_id": "7128504907803397382",
"region": "NL",
"title": "A new type of thinking #malcolmx #blackleaders #blackpeople #africancommunity #blackpower #blackunity #panafricanism #fyp #foryou #panafrican #afrikancommunity #blackconsciousness #blackcommunity #unlearnandrelearn #blackexcellence #problack #knowthyself #ubuntu",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/faca00b819ce4e9bad1ec0cb8cbe6d63_1659734391?x-expires=1703124000&x-signature=iuELTcdjUHK1EjDlrDB%2FYRaEdws%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/13d5e51f74a94aaab819798d08c1f86d_1659734391~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=FMv9WMW2COiSjgkJyO437KGKCBU%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 52,
"play": "https://v19.tiktokcdn-us.com/5a0e715186b2fbfc8132b11429969df5/6582a3ae/video/tos/useast2a/tos-useast2a-pve-0068/352bd236bd0b4a3a8d2213fa503d0a9a/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1208&bt=604&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=aDNmaTpmZDQ1ZzlkODlnNUBpM3Y5bWg6ZnlyZTMzNzczM0A0MTU0MS4vXmMxMTE1LzQvYSNgMTVicjQwZGpgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"wmplay": "https://v19.tiktokcdn-us.com/76add4e2a195de9c9b2cc8a1fef7b93b/6582a3ae/video/tos/useast2a/tos-useast2a-ve-0068c004/81c10525667444f889c96ca540674e07/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1244&bt=622&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=Nzw1Zjs5OWRoNjU1NmlnZkBpM3Y5bWg6ZnlyZTMzNzczM0BeLzFiXjJjX2ExMzRhMzNjYSNgMTVicjQwZGpgLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00008000",
"music": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7128504954595412741.mp3",
"music_info": {
"id": "7128504937776679686",
"title": "original sound - afrikancommunity",
"play": "https://sf16-ies-music-va.tiktokcdn.com/obj/musically-maliva-obj/7128504954595412741.mp3",
"cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_1080x1080.jpeg?x-expires=1703124000&x-signature=kP1cVyhAwezOqb3NoY3PVxO9Oyo%3D",
"author": "afrikancommunity",
"original": true,
"duration": 52,
"album": ""
},
"play_count": 1925864,
"digg_count": 187364,
"comment_count": 4708,
"share_count": 22382,
"download_count": 24979,
"create_time": 1659734390,
"anchors": null,
"anchors_extras": "",
"is_ad": false,
"commerce_info": {
"adv_promotable": false,
"auction_ad_invited": false,
"branded_content_type": 0,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "6813642741462287365",
"unique_id": "afrikancommunity",
"nickname": "afrikancommunity",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/93c33be7e299ea8cf1762b3ff08175bc~c5_300x300.jpeg?x-expires=1703124000&x-signature=QIJZsNfd2YOgDg8lMGEqGQeam24%3D"
},
"is_top": 0
},
{
"aweme_id": "v09044g40000ck0isu3c77u97chrtho0",
"video_id": "7278150686989159685",
"region": "ZA",
"title": "#music #amapiano #mellowandsleazy #tmanxpress #SAMA28 ",
"cover": "https://p16-sign-va.tiktokcdn.com/obj/tos-maliva-p-0068/4214065b3b6f4009b2e4808493fbd2d0_1694576516?x-expires=1703124000&x-signature=QyQVCscBgVlZQ8bodf4uS6htdfc%3D&s=SEARCH&se=false&sh=&sc=dynamic_cover&l=20231220021905B0B31567CD73EF000289",
"origin_cover": "https://p16-sign-va.tiktokcdn.com/tos-maliva-p-0068/d06fe6a869dc4f869f18a9e1ed0b3887_1694576523~tplv-tiktokx-360p.webp?x-expires=1703124000&x-signature=e7hRfKon9cvBKqt8Y8%2BkxvIwvlg%3D&s=SEARCH&se=false&sh=&sc=feed_cover&l=20231220021905B0B31567CD73EF000289",
"duration": 59,
"play": "https://v16m.tiktokcdn-us.com/4dbf46e2875addad8d023ad4a99249e7/6582a3b5/video/tos/useast2a/tos-useast2a-ve-0068c003/okMkjuDIQBQl4vAbkXeJCkA9gy5dfEAdnBSRgS/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=1718&bt=859&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=6&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=4&rc=NDxoZmU3Zjc3Njg0aTVlNkBpM2t1Zjw6ZnhsbjMzNzczM0AzYjBiYTEuNmIxNTRhMWAyYSNscWU0cjQwcC1gLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00010000",
"wmplay": "https://v16m.tiktokcdn-us.com/d4b759e76706f51d9400f0c172b11afc/6582a3b5/video/tos/useast2a/tos-useast2a-pve-0068/owIAJI4Endn5SBLxQDb5AZQ7eedkLlBEzSwRHB/?a=1233&ch=0&cr=13&dr=0&lr=all&cd=0%7C0%7C0%7C&cv=1&br=3264&bt=1632&bti=NEBzNTY6QGo6OjZALnAjNDQuYCMxNDNg&cs=0&ds=3&ft=kJrRfy7oZtc0PD1Agptxg9wp6DhXvEeC~&mime_type=video_mp4&qs=0&rc=ODw6PDQ3PDhoOTU1OzppZkBpM2t1Zjw6ZnhsbjMzNzczM0AzLTU0YDQ0XmExMWFeXjFeYSNscWU0cjQwcC1gLS1kMTZzcw%3D%3D&l=20231220021905B0B31567CD73EF000289&btag=e00010000",
"music": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/o0DzM4MSCXFMRonTCAb3e2FgOYIfy1weDJpJSa",
"music_info": {
"id": "7264936944639330305",
"title": "Imnandi lento (feat. Tman Xpress)",
"play": "https://sf16-ies-music-sg.tiktokcdn.com/obj/tos-alisg-ve-2774/o0DzM4MSCXFMRonTCAb3e2FgOYIfy1weDJpJSa",
"cover": "https://p16-sg.tiktokcdn.com/aweme/720x720/tos-alisg-v-2774/oEk3DTvnEAJSBQ6tESAczBCoAZetLQbGugfn7D.jpeg",
"author": "",
"original": false,
"duration": 60,
"album": "Imnandi lento (feat. Tman Xpress)"
},
"play_count": 3087192,
"digg_count": 182514,
"comment_count": 652,
"share_count": 11954,
"download_count": 38,
"create_time": 1694576513,
"anchors": null,
"anchors_extras": "",
"is_ad": true,
"commerce_info": {
"ad_source": 1,
"adv_promotable": true,
"auction_ad_invited": false,
"bc_label_test_text": "Paid partnership",
"branded_content_type": 4,
"with_comment_filter_words": false
},
"commercial_video_info": "",
"author": {
"id": "7276322982490014725",
"unique_id": "ubuntuedits",
"nickname": "UBUNTU",
"avatar": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/e9229e849809078be4bb64b959b4e08d~c5_300x300.jpeg?x-expires=1703124000&x-signature=eRgWDhD7lrp6A7r1IOKMfRggyPY%3D"
},
"is_top": 0
}
],
"cursor": 10,
"hasMore": true
}
}

View File

@@ -1,52 +0,0 @@
import json
import os
from googleapiclient.discovery import build
import socket
socket.setdefaulttimeout(500)
def search_youtube(api_key, query, max_results=50):
youtube = build('youtube', 'v3', developerKey=api_key)
search_response = youtube.search().list(
q=query,
part="id,snippet",
maxResults=max_results,
type="video"
).execute()
videos = []
for search_result in search_response.get("items", []):
if search_result["id"]["kind"] == "youtube#video":
video_id = search_result["id"]["videoId"]
video_metadata = get_video_metadata(api_key, video_id)
videos.append(video_metadata)
return videos
def get_video_metadata(api_key, video_id):
youtube = build('youtube', 'v3', developerKey=api_key)
request = youtube.videos().list(
part="snippet,contentDetails,statistics",
id=video_id
)
response = request.execute()
return response
api_key = 'AIzaSyDI_BBExs-HypVZFxgnR5tj5S6-uKyU4vk' # Replace with your actual API key
# Search for videos related to "VLC player"
vlc_related_videos = search_youtube(api_key, "LibreOffice Impress Tutorial", max_results=10)
# create data folder if not exist
if not os.path.exists("data"):
os.makedirs("data")
for video in vlc_related_videos:
# store the video metadata into a json file
with open(f"data/{video['etag']}.json", "w") as f:
json.dump(video, f, indent=4)

View File

@@ -1,52 +0,0 @@
import json
import os
from googleapiclient.discovery import build
import socket
socket.setdefaulttimeout(500)
def search_youtube(api_key, query, max_results=50):
youtube = build('youtube', 'v3', developerKey=api_key)
search_response = youtube.search().list(
q=query,
part="id,snippet",
maxResults=max_results,
type="video"
).execute()
videos = []
for search_result in search_response.get("items", []):
if search_result["id"]["kind"] == "youtube#video":
video_id = search_result["id"]["videoId"]
video_metadata = get_video_metadata(api_key, video_id)
videos.append(video_metadata)
return videos
def get_video_metadata(api_key, video_id):
youtube = build('youtube', 'v3', developerKey=api_key)
request = youtube.videos().list(
part="snippet,contentDetails,statistics",
id=video_id
)
response = request.execute()
return response
api_key = 'AIzaSyDI_BBExs-HypVZFxgnR5tj5S6-uKyU4vk' # Replace with your actual API key
# Search for videos related to "VLC player"
vlc_related_videos = search_youtube(api_key, "LibreOffice Calc Tutorial", max_results=10)
# create data folder if not exist
if not os.path.exists("data"):
os.makedirs("data")
for video in vlc_related_videos:
# store the video metadata into a json file
with open(f"data/{video['etag']}.json", "w") as f:
json.dump(video, f, indent=4)

View File

@@ -1,52 +0,0 @@
import json
import os
from googleapiclient.discovery import build
import socket
socket.setdefaulttimeout(500)
def search_youtube(api_key, query, max_results=50):
youtube = build('youtube', 'v3', developerKey=api_key)
search_response = youtube.search().list(
q=query,
part="id,snippet",
maxResults=max_results,
type="video"
).execute()
videos = []
for search_result in search_response.get("items", []):
if search_result["id"]["kind"] == "youtube#video":
video_id = search_result["id"]["videoId"]
video_metadata = get_video_metadata(api_key, video_id)
videos.append(video_metadata)
return videos
def get_video_metadata(api_key, video_id):
youtube = build('youtube', 'v3', developerKey=api_key)
request = youtube.videos().list(
part="snippet,contentDetails,statistics",
id=video_id
)
response = request.execute()
return response
api_key = 'AIzaSyDI_BBExs-HypVZFxgnR5tj5S6-uKyU4vk' # Replace with your actual API key
# Search for videos related to "VLC player"
vlc_related_videos = search_youtube(api_key, "Thunderbird Tutorial", max_results=10)
# create data folder if not exist
if not os.path.exists("data"):
os.makedirs("data")
for video in vlc_related_videos:
# store the video metadata into a json file
with open(f"data/{video['etag']}.json", "w") as f:
json.dump(video, f, indent=4)

View File

@@ -1,52 +0,0 @@
import json
import os
from googleapiclient.discovery import build
import socket
socket.setdefaulttimeout(500)
def search_youtube(api_key, query, max_results=50):
youtube = build('youtube', 'v3', developerKey=api_key)
search_response = youtube.search().list(
q=query,
part="id,snippet",
maxResults=max_results,
type="video"
).execute()
videos = []
for search_result in search_response.get("items", []):
if search_result["id"]["kind"] == "youtube#video":
video_id = search_result["id"]["videoId"]
video_metadata = get_video_metadata(api_key, video_id)
videos.append(video_metadata)
return videos
def get_video_metadata(api_key, video_id):
youtube = build('youtube', 'v3', developerKey=api_key)
request = youtube.videos().list(
part="snippet,contentDetails,statistics",
id=video_id
)
response = request.execute()
return response
api_key = 'AIzaSyDI_BBExs-HypVZFxgnR5tj5S6-uKyU4vk' # Replace with your actual API key
# Search for videos related to "VLC player"
vlc_related_videos = search_youtube(api_key, "Ubuntu Desktop Tutorial", max_results=10)
# create data folder if not exist
if not os.path.exists("data"):
os.makedirs("data")
for video in vlc_related_videos:
# store the video metadata into a json file
with open(f"data/{video['etag']}.json", "w") as f:
json.dump(video, f, indent=4)

View File

@@ -1,65 +0,0 @@
import json
import os
from googleapiclient.discovery import build
def search_youtube(api_key, query, max_results=50, language="en"):
youtube = build('youtube', 'v3', developerKey=api_key)
videos = []
next_page_token = None
total_results = 0
while True:
search_response = youtube.search().list(
q=query,
part="id,snippet",
maxResults=max_results,
pageToken=next_page_token,
type="video",
relevanceLanguage=language
).execute()
video_ids = [item['id']['videoId'] for item in search_response.get("items", []) if
item['id']['kind'] == 'youtube#video']
# Fetch metadata for each video
videos.extend([get_video_metadata(api_key, video_id) for video_id in video_ids])
total_results += len(video_ids)
next_page_token = search_response.get('nextPageToken')
if not next_page_token or total_results >= max_results:
break
# Sort videos by view count
sorted_videos = sorted(videos, key=lambda x: int(x['items'][0]['statistics']['viewCount']), reverse=True)
return sorted_videos
def get_video_metadata(api_key, video_id):
youtube = build('youtube', 'v3', developerKey=api_key)
request = youtube.videos().list(
part="snippet,contentDetails,statistics",
id=video_id
)
response = request.execute()
return response
api_key = 'API_KEY' # Replace with your actual API key
# Search for videos related to "VLC player"
vlc_related_videos = search_youtube(api_key, "VLC player", max_results=10)
# create data folder if not exist
if not os.path.exists("data"):
os.makedirs("data")
for video in vlc_related_videos:
# store the video metadata into a json file
with open(f"data/{video['etag']}.json", "w") as f:
json.dump(video, f, indent=4)