Skip to content
This repository was archived by the owner on Mar 31, 2020. It is now read-only.

Slithering Snacks #18

Open
wants to merge 103 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
e461f44
Add copyright
MarkKoz Feb 23, 2019
c3c3a4f
Configure flake8
MarkKoz Feb 23, 2019
7b73cc9
Add team name to readme
MarkKoz Feb 23, 2019
8da2f21
Add PySide2 dependency
MarkKoz Feb 23, 2019
e495b20
Add header to flake8 config
MarkKoz Feb 23, 2019
5b95678
Add qmake project
MarkKoz Feb 23, 2019
7999493
Add a "local" gitconfig
MarkKoz Feb 23, 2019
b15dd4a
explore meta data from ffprobe and fffmpeg
Klettgau Feb 23, 2019
e119faf
Add "add files" action to menu bar
MarkKoz Feb 24, 2019
90a04d6
Remove toolbar
MarkKoz Feb 24, 2019
5a1a08a
Display MainWindow widget
MarkKoz Feb 24, 2019
973abc1
Implement adding media to the playlist
MarkKoz Feb 24, 2019
4b6ecb7
Display playlist media in the tree view
MarkKoz Feb 24, 2019
02d1001
Create database
MarkKoz Feb 25, 2019
588394e
Add a media metadata parser
MarkKoz Feb 25, 2019
5309ade
Specify encoding for subprocess.run
MarkKoz Feb 25, 2019
4584242
Merge branch 'master' of https://github.com/chris13888/code-jam-4 int…
Klettgau Feb 25, 2019
ecfd122
Crude add SQL query and removed the formatting of ffprobe response
Klettgau Feb 25, 2019
b0f832e
Add stdout logger
MarkKoz Feb 25, 2019
0d0e65e
Replace raising exceptions with logging
MarkKoz Feb 25, 2019
8ce6ecc
Rewrite add_entry to access the db via Qt APIs
MarkKoz Feb 25, 2019
3208567
Fix driver name
MarkKoz Feb 25, 2019
f4f3bdc
Make all tags lowercase
MarkKoz Feb 25, 2019
495fa7c
Rearrange columns in library table
MarkKoz Feb 25, 2019
edb96b2
Log add_media query errors
MarkKoz Feb 25, 2019
58efdc7
Remove Meta_Data.py
MarkKoz Feb 25, 2019
587282c
Clean-up
MarkKoz Feb 25, 2019
b1767ba
Use QSqlTableModel for the view
MarkKoz Feb 26, 2019
385f333
Enable sorting on the table
MarkKoz Feb 26, 2019
1a33a9d
Hide columns instead of removing them from the model
MarkKoz Feb 26, 2019
cf954bc
Add media to the table via the model rather than direct SQL
MarkKoz Feb 26, 2019
ae8bd5e
Only allow a single row to be selected in the table
MarkKoz Feb 27, 2019
152edf1
Remove playlist model
MarkKoz Feb 27, 2019
da980bc
Rename library to playlist
MarkKoz Feb 27, 2019
0a5d4df
Minor refactor to MainWindow
MarkKoz Feb 27, 2019
30a91e0
Subclass QMediaPlaylist to use the model for retrieving media
MarkKoz Feb 27, 2019
c28a3f1
Fix current media always being None
MarkKoz Feb 27, 2019
0d8c6a2
Adds password ui and command to make it appear. Input not implemented.
chris13888 Feb 27, 2019
2484034
Add bidict dependency
MarkKoz Feb 27, 2019
a1c0df4
Rewrite Playlist wrapper
MarkKoz Feb 27, 2019
7133bf6
Refactor password prompt
MarkKoz Feb 27, 2019
632b2eb
Make ui.MainWindow an attribute rather than subclassing
MarkKoz Feb 27, 2019
0a898c3
Log mediaStatusChanged for player
MarkKoz Feb 28, 2019
e97195e
Use file name as title if a title tag doesn't exist
MarkKoz Feb 28, 2019
39a4e1e
Implement Playlist.removeMedia
MarkKoz Feb 28, 2019
ae3ada2
Populate playlist when it's created with existing media in the model
MarkKoz Feb 28, 2019
4efbd63
Check for success when adding media to the playlist
MarkKoz Feb 28, 2019
f202fda
Initially sort playlist by id in ascending order
MarkKoz Mar 1, 2019
41cebb2
Fix import order
MarkKoz Mar 1, 2019
2b5dfb7
Refactor playlist code to a separate class
MarkKoz Mar 1, 2019
61ad19c
Move some code from MainWindow.__init__ into separate functions
MarkKoz Mar 1, 2019
02ac0c9
Add context menu to table with a remove action
MarkKoz Mar 1, 2019
0a8f844
Use transaction control for adding/removing media
MarkKoz Mar 1, 2019
b09c925
Connect the remove context menu action
MarkKoz Mar 1, 2019
ad96973
Connect the triggered signal of the remove context menu action
MarkKoz Mar 1, 2019
c500e11
Added functionality for password checking. Added temporary password.
chris13888 Mar 1, 2019
cc0cc31
Stop playing if the current media is removed
MarkKoz Mar 2, 2019
d9cc7eb
Fix playlist index not initially changing when play is pressed
MarkKoz Mar 2, 2019
d356980
Add media to playlist after committing
MarkKoz Mar 2, 2019
aa42437
Specify the media id when adding media instead of the row
MarkKoz Mar 2, 2019
cd2de96
Move password constant to the password_prompt module
MarkKoz Mar 2, 2019
c7cbc67
Set initial media to be the first row
MarkKoz Mar 2, 2019
546c5e9
Use a dict for storing media in Playlist instead of internal QList
MarkKoz Mar 2, 2019
45fefd9
Add a NotImplementedError stub for insertMedia
MarkKoz Mar 2, 2019
f393636
Changed password to passphrase. Added comments.
chris13888 Mar 2, 2019
8e46d05
Removed unnecessary flake8 from Pipfile, changed PasswordPrompt.succe…
chris13888 Mar 2, 2019
1c74e1d
Added PasswordPrompt instance to MainWindow.
chris13888 Mar 2, 2019
e5894d6
Moved location of create_db function
chris13888 Mar 2, 2019
7f534c7
Changed how password is entered.
chris13888 Mar 2, 2019
715fc0c
reverted bad changes in previous commit
chris13888 Mar 2, 2019
5367b9f
Fixed bugs
chris13888 Mar 2, 2019
9625afa
Added password creation stub
chris13888 Mar 2, 2019
fd5ca7f
Fix lint errors
MarkKoz Mar 3, 2019
05fbc98
Update LCD with time remaining
MarkKoz Mar 3, 2019
cda4f58
Add seek dialogue
MarkKoz Mar 3, 2019
27a2b52
Implement seeking via the seek dialogue
MarkKoz Mar 3, 2019
23e2bd3
Update the duration and position of the seek dialogue dials
MarkKoz Mar 3, 2019
4bbf4a3
Disable seeking when there's no current media
MarkKoz Mar 3, 2019
94492ca
Make the play button toggle between play and pause
MarkKoz Mar 3, 2019
8b3d8c2
Configure the view in the designer instead of programmatically
MarkKoz Mar 3, 2019
4e2fef6
Add tooltips to seek dialogue's LCDs
MarkKoz Mar 3, 2019
01bae92
Use grid layout for MainWindow
MarkKoz Mar 3, 2019
e0afea0
Set parent of seek dialogue so that it is modal
MarkKoz Mar 3, 2019
c8a28d3
Add annoying confirmation message boxes when removing media
MarkKoz Mar 3, 2019
4d27acd
Add description and instructions to README
MarkKoz Mar 3, 2019
88cfa9f
Fix error when attempting to add media when no media was selected
MarkKoz Mar 3, 2019
3f7961d
Don't try to parse stdout as JSON is return code is non-zero
MarkKoz Mar 3, 2019
69d9bf9
Stretch columns
MarkKoz Mar 3, 2019
88cda51
Style the row for the currently playing media
MarkKoz Mar 3, 2019
dcace00
Add dark stylesheet
MarkKoz Mar 3, 2019
3a78c98
Changed password creation.
chris13888 Mar 3, 2019
4b1d170
converted widgets to dialogs
chris13888 Mar 3, 2019
5b17c64
Added password. Prompts to create password if not created.
chris13888 Mar 3, 2019
296305f
Add a CAPTCHA for adding files
MarkKoz Mar 3, 2019
99f427e
Changes never-closing dialogue to exit program.
chris13888 Mar 3, 2019
4f3e906
Added password prompt on play button.
chris13888 Mar 3, 2019
f6bed5e
Store password in database
MarkKoz Mar 3, 2019
645820a
Prompt for password upon app startup
MarkKoz Mar 3, 2019
9d68517
Refactor CreatePassword dialogue
MarkKoz Mar 3, 2019
64c1850
Refactor PasswordPrompt
MarkKoz Mar 3, 2019
dd29f09
Add a volume slider
MarkKoz Mar 3, 2019
bfabf0c
Add a remove dialogue
MarkKoz Mar 3, 2019
42fcadd
Add remove dialogue
MarkKoz Mar 4, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[flake8]
max-line-length=100
application_import_names=projectt
ignore=P102,B311,W503,E226,S311,W504,F821
exclude=__pycache__, venv, .venv, tests
application_import_names=project
ignore=W503,B305
exclude=__pycache__, venv, .venv, tests, project/ui
import-order-style=pycharm
inline-quotes = "
4 changes: 4 additions & 0 deletions .gitconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[core]
autocrlf = input
eol = lf
whitespace=trailing-space,space-before-tab,-indent-with-non-tab,tab-in-indent,-cr-at-eol,tabwidth=4
53 changes: 53 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,56 @@ venv.bak/

# mypy
.mypy_cache/

# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.dll
*.dylib

# Qt-es
object_script.*.Release
object_script.*.Debug
*_plugin_import.cpp
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
*.qmlc
*.jsc
Makefile*
*build-*

# Qt unit tests
target_wrapper.*

# QtCreator
*.autosave

# QtCreator Qml
*.qmlproject.user
*.qmlproject.user.*

# QtCreator CMake
CMakeLists.txt.user*

# QtCreator 4.8< compilation database
compile_commands.json

# QtCreator local machine specific files for imported projects
*creator.user*

qt/build/
library.sqlite
3 changes: 2 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
MIT License

Copyright (c) 2019 Python Discord
Original Copyright (c) 2019 Python Discord
Copyright (c) 2019 Slithering Snacks

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
11 changes: 9 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]
flake8 = "*"
flake8-bugbear = "*"
flake8-import-order = "*"
flake8-quotes = "*"
flake8-tidy-imports = "*"

[packages]
pyside2 = "*"
qdarkstyle = "*"
captcha = "*"

[requires]
python_version = "3.7"

[scripts]
lint = "python -m flake8"
lint = "python -m flake8"
start = "python -m project"
134 changes: 126 additions & 8 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 43 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

The theme for this code jam will be **This app hates you!**. You will be creating an application using a GUI library of your choice in Python. The application must serve a real purpose, but must also fit the theme.

You can use any GUI library that you wish to use, but you have to make _a desktop app_. For example, you may use frameworks like PySide, PyQt, tkinter, or wxPython. You can even use stuff like Kivy or PyGame, although we do not recommend that you do. You may not, however, use webframeworks like Django or Flask, and you may not use anything that turns HTML and CSS into a desktop app that runs as a browser.
You can use any GUI library that you wish to use, but you have to make _a desktop app_. For example, you may use frameworks like PySide, PyQt, tkinter, or wxPython. You can even use stuff like Kivy or PyGame, although we do not recommend that you do. You may not, however, use webframeworks like Django or Flask, and you may not use anything that turns HTML and CSS into a desktop app that runs as a browser.

Here are a couple of examples of what we mean by an application that "serves a real purpose but also fits the theme":
* A calculator app that calculates the right answers, but represents the answer in a way that's completely impractical.
* An image resizer where you have to specify which part of the image to resize, specify how much force to apply to the resize operation in newtons, and then manually resize the image by turning a crank.
* An alarm clock app that plays a very loud sound effect every 5 minutes reminding you that your alarm will ring in 6 hours. The closer it gets to the 6 hour mark, the lower the volume of the sound effect. When the time is up, the sound effect is virtually inaudible.

Remember that teamwork is not optional for our code jams - You must find a way to work together. For this jam, we've assigned a leader for each team based on their responses to the application form. Remember to listen to your leader, and communicate with the rest of your team!
Remember that teamwork is not optional for our code jams - You must find a way to work together. For this jam, we've assigned a leader for each team based on their responses to the application form. Remember to listen to your leader, and communicate with the rest of your team!

**Remember to provide instructions on how to set up and run your app at the bottom of this README**.

Expand All @@ -22,24 +22,60 @@ Remember that teamwork is not optional for our code jams - You must find a way t

# Setting Up

You should be using [Pipenv](https://pipenv.readthedocs.io/en/latest/). Take a look
You should be using [Pipenv](https://pipenv.readthedocs.io/en/latest/). Take a look
[at the documentation](https://pipenv.readthedocs.io/en/latest/) if you've never used it before. In short:

* Setting up for development: `pipenv install --dev`
* Running the application (assuming you use our project layout): `pipenv run start`

# Project Information

`# TODO`
Slithering Snacks's submission for the 4th code jam.

Qt, via PySide2 ("Qt for Python"), is used as the GUI framework. The Qt Multimedia module is an easy, cross-platform solution to playing media. The UI windows are designed in Qt Creator and then converted to Python using `pyside2-uic`.

SQLite is used to drive a database which persists the media playlist.

## Description

`# TODO`
A basic media player with the following features:

* Previous and next navigation of playlist
* Seeking
* Persistent and sortable playlist
* Parsing and displaying metadata tags of media

## Setup & Installation

`# TODO`
First, make sure [ffmpeg](https://ffmpeg.org/) is installed. Particularily, this program relies on `ffprobe`. It should either be on your `PATH` or in the current working directory when running the program.

Open a terminal in the repository's root directory and execute the following command to install the project's dependencies:

```bash
pipenv --sync
```

To run the program, execute

```bash
pipenv run start
```

## How do I use this thing?

`# TODO`
#### Adding media
Click on `File` in the menu bar, then click on `Add files`. In the file dialogue which opens, browse for and select the media to add to the playlist.

#### Removing media
Right click on a row in the playlist, select the `Remove` action on the context menu, and confirm removal in the prompts which appear.

#### Playing media
Click on the `Play` button to start playing media. To pause, click on the same button again. Notice that when media is playing, the button changes from `Play` to `Pause`. The `Previous` and `Next` may be used to navigate the playlist.

The time remaining on the current song can be seen below the playlist, to the left of the slider. It display the remaining time in hexadecimal.

#### Seeking
Click on the slider below the playlist to seek. In the dialogue that opens, use the dials to select the hour, minute, and second you wish to seek. Note that the values below the dials are _octal_ numbers.

#### Playlist
Media can be sorted on the playlist by clicking on the column headers. An indicator appears on the header by which the playlist is being sorted.
11 changes: 11 additions & 0 deletions project/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import logging
import os
import sys

DEBUG = os.environ.get("DEBUG", False)

logging.basicConfig(
format="%(asctime)s | %(name)-32s | %(levelname)-8s | %(message)s",
level=logging.DEBUG if DEBUG else logging.INFO,
handlers=(logging.StreamHandler(stream=sys.stdout),)
)
3 changes: 3 additions & 0 deletions project/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from project import music_player

music_player.main()
3 changes: 3 additions & 0 deletions project/delegates/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from project.delegates.current_media import CurrentMediaDelegate

__all__ = ("CurrentMediaDelegate",)
9 changes: 9 additions & 0 deletions project/delegates/current_media.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from PySide2.QtCore import QModelIndex
from PySide2.QtGui import QPainter
from PySide2.QtWidgets import QStyleOptionViewItem, QStyledItemDelegate


class CurrentMediaDelegate(QStyledItemDelegate):
def paint(self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex):
option.font.setBold(True)
super().paint(painter, option, index)
Loading