Merge lp:~ahayzen/music-app/add-url-dispatcher-album into lp:music-app/trusty
- add-url-dispatcher-album
- Merge into trusty
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Victor Thompson | ||||
Approved revision: | 433 | ||||
Merged at revision: | 414 | ||||
Proposed branch: | lp:~ahayzen/music-app/add-url-dispatcher-album | ||||
Merge into: | lp:music-app/trusty | ||||
Diff against target: |
268 lines (+105/-64) 4 files modified
CMakeLists.txt (+1/-1) com.ubuntu.music_music.url-dispatcher (+8/-0) meta-database.js (+18/-4) music-app.qml (+78/-59) |
||||
To merge this branch: | bzr merge lp:~ahayzen/music-app/add-url-dispatcher-album | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Victor Thompson | Approve | ||
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Andrew Hayzen | Approve | ||
Review via email: mp+214414@code.launchpad.net |
Commit message
* Add album:/
* Simplification of file:// handling
Description of the change
* Add album:/
* Simplification of file:// handling
Installation:
- Desktop
cd /tmp
bzr branch lp:~andrew-hayzen/music-app/add-url-dispatcher-album music-app
cd music-app
click-buddy --dir . --provision
rm -rf /tmp/music-app
- Mobile
cp -r /usr/share/
pkill unity8
Testing:
On device use the commands below to, for example, start playing the album 'Day & Age' or the track 'Flesh and Bone'.
The protocols file:// and album:// should be tested when the app is in both an open and closed state.
sudo -u phablet -i
url-dispatcher "album:///The Killers/Day & Age"
url-dispatcher "file:/
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
Michal Hruby (mhr3) wrote : | # |
9 + set(EXEC "qmlscene -qt5 ${MAIN_QML} --file=%u -I ./plugins")
Would be probably better to rename the "file" param to "url".
Andrew Hayzen (ahayzen) wrote : | # |
Good idea when I'm back at my pc I'll update it, thanks :-)
Victor Thompson (vthompson) wrote : | # |
On Trusty r278 url-dispatcher is not in $PATH and when executing the following directly:
/usr/lib/
I get the following error:
** (process:4424): ERROR **: Unable to connect to D-Bus: Cannot autolaunch D-Bus without X11 $DISPLAY
Is there something else I need to do to utilize this program?
Andrew Hayzen (ahayzen) wrote : | # |
Victor, are you logged in as the phablet user rather than root. If root run the following command to switch then try again.
sudo -u phablet -i
Victor Thompson (vthompson) wrote : | # |
I am:
root@ubuntu-
phablet@
-bash: url-dispatcher: command not found
phablet@
** (process:3060): WARNING **: Unable to get name 'com.canonical.
phablet@
I just upgraded to r279 and the error message is different than it was for my attempt with r278.
Andrew Hayzen (ahayzen) wrote : | # |
Hmmm strange IIRC I was on 227, I'm currently traveling home for easter I'll have a look when I get back.
Michal Hruby (mhr3) wrote : | # |
> On Trusty r278 url-dispatcher is not in $PATH and when executing the following
> directly:
>
> /usr/lib/
That's the url-dispatcher daemon, not the binary to launch urls, that one is in pkg url-dispatcher-
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:427
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
Michal, thank you.
Andrew, would it make sense to enforce the album uri scheme to be "album:
I'll try to review the rest shortly.
Victor Thompson (vthompson) wrote : | # |
One thing to think about is that albums and artists can have the slash "/" character in them [1]. Perhaps we should pick another delimiter? I think we should talk with the Music scope folks to see if we can come up with a better solution.
[1] http://
Michal Hruby (mhr3) wrote : | # |
> Andrew, would it make sense to enforce the album uri scheme to be
> "album:
> most URI handlers seem to indicate the root directory--which doesn't exist in
> the URI scheme we are introducing.
album:/
Victor Thompson (vthompson) wrote : | # |
Thanks again. Andrew, in that case most of this looks great. I think we should decode the album:// URI in the split array after we split the string, however.
- 428. By Andrew Hayzen
-
* Add decodeURIComponent to split album:// parameters
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:428
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
This modification breaks the fix for lp:1292921. It appears as though the decided file parameter won't no longer matches the encoded (?) file in the music library?
Victor Thompson (vthompson) wrote : | # |
Sorry, decoded file parameter
- 429. By Andrew Hayzen
-
* Add music:// protocol
* Modify URL handling - 430. By Andrew Hayzen
-
* Fix for encoding
Andrew Hayzen (ahayzen) wrote : | # |
After investigations I found that the url stored in the database is neither encoded nor decoded, it is somewhat in between.
If you have a track with the file path ending
~!@#$%^
It is stored in the database as
~!@%23$
It appears from the url-dispatcher as
~!@%23$
Therefore ; [ ] need to be switched to %3B %5B %5D and a %20 needs to be switched to a space.
Note that a / and = cannot be used in the filename as a / is used to declare a folder and a = breaks the command line arguments.
Andrew Hayzen (ahayzen) wrote : | # |
Ah international characters now cause issues such as é. Anyone got any better ideas to make the dispatcher url the same as the database url?
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:430
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 431. By Andrew Hayzen
-
* decode file before it goes in the database
- 432. By Andrew Hayzen
-
* Revert to using linear search for processFile()
Andrew Hayzen (ahayzen) wrote : | # |
I've reverting to using a linear search like before. I believe everything is fixed now, please retest :)
- 433. By Andrew Hayzen
-
* Remove tracing
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:433
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Victor Thompson (vthompson) wrote : | # |
Awesome, thanks. We'll look at a way not to do the 'needle in a haystack' linear search in the future. Nice work!
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2014-03-10 10:17:36 +0000 |
3 | +++ CMakeLists.txt 2014-04-09 20:30:41 +0000 |
4 | @@ -25,7 +25,7 @@ |
5 | set(CMAKE_INSTALL_BINDIR /) |
6 | set(DATA_DIR /) |
7 | set(ICON ${ICON_FILE}) |
8 | - set(EXEC "qmlscene -qt5 ${MAIN_QML} --file=%f -I ./plugins") |
9 | + set(EXEC "qmlscene -qt5 ${MAIN_QML} --url=%u -I ./plugins") |
10 | set(DESKTOP_DIR ${DATA_DIR}) |
11 | set(URLS_DIR ${DATA_DIR}) |
12 | else(CLICK_MODE) |
13 | |
14 | === modified file 'com.ubuntu.music_music.url-dispatcher' |
15 | --- com.ubuntu.music_music.url-dispatcher 2014-01-31 20:43:59 +0000 |
16 | +++ com.ubuntu.music_music.url-dispatcher 2014-04-09 20:30:41 +0000 |
17 | @@ -0,0 +1,8 @@ |
18 | +[ |
19 | + { |
20 | + "protocol": "album" |
21 | + }, |
22 | + { |
23 | + "protocol": "music" |
24 | + } |
25 | +] |
26 | |
27 | === modified file 'meta-database.js' |
28 | --- meta-database.js 2014-03-06 01:57:57 +0000 |
29 | +++ meta-database.js 2014-04-09 20:30:41 +0000 |
30 | @@ -123,17 +123,16 @@ |
31 | } |
32 | |
33 | // This function is used to retrieve meta data from the database |
34 | -function getMetadata(file,type) { |
35 | +function getMetadata(file) { |
36 | var db = getDatabase(); |
37 | var res=""; |
38 | |
39 | try { |
40 | db.transaction(function(tx) { |
41 | - //var rs = tx.executeSql('SELECT type=?;',[type],' FROM metadata WHERE file=?;', [file]); // tries to get the title of track |
42 | - var rs = tx.executeSql('SELECT ? FROM metadata WHERE file=?;', [type,file]); // tries to get the title of track |
43 | + var rs = tx.executeSql('SELECT * FROM metadata WHERE file=?;', [file]); // tries to get the title of track |
44 | |
45 | if (rs.rows.length > 0) { |
46 | - res = rs.rows.item(0).value; |
47 | + res = rs.rows.item(0); |
48 | } else { |
49 | res = "Unknown"; |
50 | } |
51 | @@ -335,6 +334,21 @@ |
52 | return res; |
53 | } |
54 | |
55 | +function getArtistAlbumTracks(artist, album) { |
56 | + var res = []; |
57 | + var db = getDatabase(); |
58 | + //console.log("Album: " + album); |
59 | + db.transaction( function(tx) { |
60 | + var rs = tx.executeSql("SELECT * FROM metadata WHERE artist=? AND album=? ORDER BY artist COLLATE NOCASE ASC, album COLLATE NOCASE ASC, CAST(number AS int) ASC", [artist, album]); |
61 | + for(var i = 0; i < rs.rows.length; i++) { |
62 | + var dbItem = rs.rows.item(i); |
63 | + //console.log("Artist:"+ dbItem.artist + ", Album:"+dbItem.album + ", Title:"+dbItem.title + ", File:"+dbItem.file + ", Art:"+dbItem.cover + ", Genre:"+dbItem.genre); |
64 | + res.push({artist:dbItem.artist, album:dbItem.album, title:dbItem.title, file:dbItem.file, cover:dbItem.cover, length:dbItem.length, year:dbItem.year, genre:dbItem.genre}); |
65 | + } |
66 | + }); |
67 | + return res; |
68 | +} |
69 | + |
70 | function getGenres() { |
71 | var res = []; |
72 | var db = getDatabase(); |
73 | |
74 | === modified file 'music-app.qml' |
75 | --- music-app.qml 2014-03-28 18:59:23 +0000 |
76 | +++ music-app.qml 2014-04-09 20:30:41 +0000 |
77 | @@ -117,7 +117,7 @@ |
78 | //defaultArgument.valueNames: ["URI"] // should be used when bug is resolved |
79 | // grab a file |
80 | Argument { |
81 | - name: "file" |
82 | + name: "url" |
83 | help: "URI for track to run at start." |
84 | required: false |
85 | valueNames: ["track"] |
86 | @@ -198,42 +198,85 @@ |
87 | // (already in the database), not e.g. http:// URIs or files in directories |
88 | // not picked up by Grilo |
89 | Connections { |
90 | + id: uriHandler |
91 | target: UriHandler |
92 | + |
93 | + function processAlbum(uri) { |
94 | + var split = uri.split("/"); |
95 | + |
96 | + if (split.length < 2) { |
97 | + console.debug("Unknown artist-album " + uri + ", skipping") |
98 | + return; |
99 | + } |
100 | + |
101 | + // Get tracks |
102 | + var tracks = Library.getArtistAlbumTracks(decodeURIComponent(split[0]), decodeURIComponent(split[1])); |
103 | + |
104 | + if (tracks.length === 0) { |
105 | + console.debug("Unknown artist-album " + uri + ", skipping") |
106 | + return; |
107 | + } |
108 | + |
109 | + // Enqueue |
110 | + for (var track in tracks) { |
111 | + trackQueue.append(tracks[track]); |
112 | + } |
113 | + |
114 | + // Play first track |
115 | + trackClicked(trackQueue, 0, true); |
116 | + } |
117 | + |
118 | + function processFile(uri, play) { |
119 | + uri = decodeURIComponent(uri); |
120 | + |
121 | + // search for path in library |
122 | + var library = Library.getAll(); |
123 | + var track = false; |
124 | + |
125 | + for (var item in library) { |
126 | + if (decodeURIComponent(library[item].file) === uri) { |
127 | + track = library[item]; |
128 | + break; |
129 | + } |
130 | + } |
131 | + |
132 | + if (!track) { |
133 | + console.debug("Unknown file " + uri + ", skipping") |
134 | + return; |
135 | + } |
136 | + |
137 | + // enqueue |
138 | + trackQueue.append(track); |
139 | + |
140 | + // play first URI |
141 | + if (play) { |
142 | + trackClicked(trackQueue, 0, true) |
143 | + } |
144 | + } |
145 | + |
146 | + function process(uri, play) { |
147 | + if (uri.indexOf("album:///") === 0) { |
148 | + uriHandler.processAlbum(uri.substring(9)); |
149 | + } |
150 | + else if (uri.indexOf("file://") === 0) { |
151 | + uriHandler.processFile(uri.substring(7), play); |
152 | + } |
153 | + else if (uri.indexOf("music://") === 0) { |
154 | + uriHandler.processFile(uri.substring(8), play); |
155 | + } |
156 | + |
157 | + else { |
158 | + console.debug("Unsupported URI " + uri + ", skipping") |
159 | + } |
160 | + } |
161 | + |
162 | onOpened: { |
163 | // clear play queue |
164 | trackQueue.model.clear() |
165 | for (var i=0; i < uris.length; i++) { |
166 | console.debug("URI=" + uris[i]) |
167 | - // skip non-file:// URIs |
168 | - if (uris[i].substring(0, 7) !== "file://") { |
169 | - console.debug("Unsupported URI " + uris[i] + ", skipping") |
170 | - continue |
171 | - } |
172 | - |
173 | - // search pathname in library |
174 | - var file = decodeURIComponent(uris[i]) |
175 | - var index = -1; |
176 | - |
177 | - for (var j=0; j < griloModel.count; j++) |
178 | - { |
179 | - if (decodeURIComponent(griloModel.get(j).url.toString()) == file) |
180 | - { |
181 | - index = j; |
182 | - } |
183 | - } |
184 | - |
185 | - if (index <= -1) { |
186 | - console.debug("Unknown file " + file + ", skipping") |
187 | - continue |
188 | - } |
189 | - |
190 | - // enqueue |
191 | - trackQueue.append(griloModel.get(index)); |
192 | - |
193 | - // play first URI |
194 | - if (i == 0) { |
195 | - trackClicked(trackQueue, 0, true) |
196 | - } |
197 | + |
198 | + uriHandler.process(uris[i], i === 0); |
199 | } |
200 | } |
201 | } |
202 | @@ -280,19 +323,6 @@ |
203 | customdebug("Arguments on startup: Debug: "+args.values.debug) |
204 | |
205 | customdebug("Arguments on startup: Debug: "+args.values.debug+ " and file: ") |
206 | - if (args.values.file) { |
207 | - argFile = args.values.file |
208 | - if (argFile.indexOf("file://") != -1) { |
209 | - //customdebug("arg contained file://") |
210 | - // strip that! |
211 | - argFile = argFile.substring(7) |
212 | - } |
213 | - else { |
214 | - // do nothing |
215 | - customdebug("arg did not contain file://") |
216 | - } |
217 | - customdebug(argFile) |
218 | - } |
219 | |
220 | Settings.initialize() |
221 | console.debug("INITIALIZED in tracks") |
222 | @@ -333,7 +363,6 @@ |
223 | property string lastfmusername |
224 | property string lastfmpassword |
225 | property string timestamp // used to scrobble |
226 | - property string argFile // used for argumented track |
227 | property var chosenElement: null |
228 | property LibraryListModel currentModel: null // Current model being used |
229 | property var currentQuery: null |
230 | @@ -638,8 +667,6 @@ |
231 | } |
232 | |
233 | onFinished: { |
234 | - var read_arg = false; |
235 | - |
236 | // FIXME: remove when grilo is fixed |
237 | var files = []; |
238 | var duplicates = 0; |
239 | @@ -673,18 +700,6 @@ |
240 | genre: media.genre || i18n.tr("Unknown Genre") |
241 | }; |
242 | |
243 | - if (read_arg === false && decodeURIComponent(argFile) === decodeURIComponent(file)) |
244 | - { |
245 | - trackQueue.model.clear(); |
246 | - trackQueue.model.append(record) |
247 | - trackClicked(trackQueue, 0, true); |
248 | - |
249 | - // grilo model sometimes has duplicates |
250 | - // causing the track to be paused the second time |
251 | - // this ignores the second time |
252 | - read_arg = true; |
253 | - } |
254 | - |
255 | //console.log("Artist:"+ media.artist + ", Album:"+media.album + ", Title:"+media.title + ", File:"+file + ", Cover:"+media.thumbnail + ", Number:"+media.trackNumber + ", Genre:"+media.genre); |
256 | Library.setMetadata(record) |
257 | } |
258 | @@ -694,6 +709,10 @@ |
259 | console.debug("Grilo duplicates:", duplicates); // FIXME: remove when grilo is fixed |
260 | griloModel.loaded = true |
261 | tabs.ensurePopulated(tabs.selectedTab); |
262 | + |
263 | + if (args.values.url) { |
264 | + uriHandler.process(args.values.url, true); |
265 | + } |
266 | } |
267 | } |
268 | } |
PASSED: Continuous integration, rev:425 91.189. 93.70:8080/ job/music- app-ci/ 688/ 91.189. 93.70:8080/ job/generic- mediumtests- trusty/ 1999 91.189. 93.70:8080/ job/music- app-raring- amd64-ci/ 688 91.189. 93.70:8080/ job/music- app-saucy- amd64-ci/ 690 91.189. 93.70:8080/ job/music- app-trusty- amd64-ci/ 409
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: 91.189. 93.70:8080/ job/music- app-ci/ 688/rebuild
http://