Wednesday, April 9, 2014

Week14 Blog10: Unexpected Travis Build Fail

As a final check for my work this term, I decided to run the unit tests and flake8 once again. Both went well on my computer. So I committed and pushed the final version to my github repo.

Then an unexpected event came up: the Travis CI Build failed!

All of the unit tests and flake8 passed in the travis build. However, right after the green message "174 passed, 1 skipped", it threw the error:
"Inconsistency detected by ld.so: dl-close.c: 759: _dl_close: Assertion `map->l_init_called' failed!"

Note that the error didn't come from the "1 skipped", since the last successful travis build in master also had "1 skipped".
The issue probably had something to do with the library I was trying to install in Travis.
In .travis.yml, I added the line:
sudo apt-get install python-qt4-phonon phonon-backend-gstreamer
(Note: we cannot install PyQt4's phonon with pip, because I couldn't find PyQt4 phonon in pypi. Instead, there was only PySide's phonon)
So, with this idea in mind, I tried to fix the problem by looking for another way to install phonon. However, I wasn't able to find another way of installation that made phonon work properly.

So in the end, I decided to look for another way to play sound. From the discussion with Thanh on IRC last week, it seems that Snack is a small library that we can use. After some research and experimentation, I got the sound working with Snack. The advantage of this library is that I generated the alert sound by using a sine frequency to make a musical note. This way, we don't need to store an additional binary file (alert.mp3) and its license anymore.

The new dependencies can be installed using:
sudo apt-get install libsnack2
sudo apt-get install libsnack2-dev
sudo apt-get install libsnack2-alsa
sudo apt-get install python-tksnack

Thursday, April 3, 2014

Week13 Blog9

Progress I made
  • Fixed problem found by test case last week, where we have talks A B, all in room 123, B's start time between start and end time of A. In this case the recording for B should not start
  • Added alert sound's license
  • For the implementation of alert sound, changed from using pygame to Phonon
  • Finished the project proposal

Problems
  • Before switching to Phonon, tried to search more about using QSound. But it turned out that for QSound to be available in Ubuntu, we need to compile Qt with NAS (from the discussion with Thanh on IRC). For our purposes, using QSound is not the ideal way to do it

This is the last week before the project deadline and the end of the term, so this will be the last blog. There are no plans for next week.


Thursday, March 27, 2014

Week12 Blog8

Progress I made
  1. Following the discussions in last week's meeting, I changed the alert sound from the system notification sound to an external sound, played using pygame.
  2. Squashed and rebased all commits
  3. Tested auto-recording using the test cases below
 Test cases:

- Empty case
  • No talks in database
- "No talks available" dialog box 
  • talk A, has room number, start time already passed
  • talk A, no room number, start time later than current time
  • talk A, room 123, set to a different later date
  • talks A B C, all have same room number, all with starting times that have already passed
  • talks A B C, A B have same room numbers, C has different room number, all with starting times that have already passed
  • talks A B C, A B have same room numbers, C has different room number, A B start time passed, C start time later than current time, but room number selected in the recording interface is the room for talk A
- "No room selected" dialog box (room field empty in recording interface)
  • talk A, has room number, start time later than current time
- One talk available (room 123 selected)
  • talk A, room 123, start time later than current time
  • talks A B C, A B have no room number, C room 123, all start time later than current time
  • talks A B C, A C room 456, B room 123, all start time later than current time
  • talks A B, all in room 123, B's start time between start and end time of A (need to fix!) 
- More than one talk available (room 123 selected)
  • talks A B C, A C room 123, B room 456, all start time later than current time
  • talks A B C, all in room 123, A C start time later than current time, B start time passed
  • talks A B C, all in room 123, all start time later than current time
- Stop auto-record (room 123 selected)
  • talks A B C, all in room 123, all start time later than current time,press "Stop Auto-Record" before recording starts
  • talks A B C, all in room 123, all start time later than current time,press "Stop Auto-Record" in the middle of a recording
- Countdown display + flash screen + alert sound
  • talk A, room 123, set start time to 2 hours after current time
  • talk A, room 123, set start time to 3 minutes after current time
  • talk A, room 123, set start time to 1.5 minutes after current time
  • talk A, room 123, set start time to 20 seconds after current time
  • talk A, room 123, set duration to 3 minutes 10 seconds
  • talk A, room 123, set duration to 1.5 minutes
  • talk A, room 123, set duration to 20 seconds
- Length of recording (check the talk is recorded properly and saved in the video directory)
  • talk A, room 123, set duration to 1 minute
  • talk A, room 123, set duration to 10 seconds
Also check that when in auto-record mode, all buttons in recording interface are disabled, and the Stop Auto-Record button is pressed down.

Plans for next week
  • Fix problem found by test case above
  • Find out the alert sound's license
  • Try to change from using pygame to QSound
  • Edit, polish, and finish the project proposal
  • Request for code review and make any last modifications to the files in the pull request

Problems
None. Thanks to Dennis and Thanh, finally figured out an easier way to rebase to master!


Saturday, March 22, 2014

UCOSP Reflections

This semester, I joined the Freeseer project as part of the UCOSP project course. The project was a new challenge for me, but at the same time, it was very enjoyable. Now the term has almost come to an end, and I'd like to share some thoughts about this valuable experience.


About Freeseer & My Role In It

Freeseer is a free, open source, cross-platform application used to capture presentations. It has been used at many open source conferences to record hundreds of talks. The way Freeseer works is simple: first, store information about the talks you want to record, including the title, event, speaker, room, date and start time. Next, set up the external cables and connections for recording. Then, select the current talk to record, and Freeseer will capture the speaker's laptop screen along with the presentation talk.

My project this term was to implement a new auto-recording feature for Freeseer. This feature detects when a talk is starting/ending, and automatically records it. This would allow a laptop doing the recording to automatically record all the talks in a room without the need of a volunteer to monitor it. For this feature to work, we first store an additional end time of a talk on top of the start time. Then, if the user presses the auto-record button, we search for all the talks starting at or after the current computer time, in the specified room. If no talks satisfy these conditions, a dialog box pops up, informing the user that no such talks are available. Otherwise, we enter a fullscreen mode that displays the title and speaker of the next talk to be recorded, and the countdown until the start of the recording. As the time to start recording approaches, the screen flashes, and an alert sound plays to remind the speaker to get ready. During the recording, there is a similar countdown informing the speaker how much time he/she has left until the end of the recording. After this recording, the cycle repeats again.


Reflections About My Project

It was really fun to implement the auto-recording feature because, not only did I get to familiarize myself with the existing code in the Freeseer repository, but I also got to learn lots of cool new techniques, such as how to use PyQt4's QTimer to simulate a countdown, how to show changing countdown display messages, how to use system notification sounds as alert sounds, etc.

While doing the project, I've also encountered some roadblocks along the way. There were times when I spent a whole day trying to find a bug in a function, carefully debugging and showing the state of the variables after every line, and still hadn't found the source of the problem. Then, in my devastation, I finally switched to another method to implement this function, and TA-DA! It worked! Because of these kind of failures, I have learned to become more flexible with programming.

We were required to keep blog posts about the progress we made each week, what we planned to do next week, and any issues/concerns we had. At first this seemed like a burden, but soon, I found keeping blog posts very helpful! Since I also had to think about assignments/lectures for other courses, it was impossible to work on Freeseer every day of the week. So, when I returned to work on the project one week later, I could barely remember anything from last week, or what I should be working on next. Thus I relied heavily on my blog posts to keep me on track. It was also quite easy to write the post! I only needed to keep a note of what I just did after I completed each task, while it was still fresh in my mind.


Tips For Students Doing UCOSP Next Year

  • This semester, the code sprint was scheduled to be later than in previous years, so the students were less motivated to start working right away, and the pace was slower than usual. However, it's a good idea to start early because when doing programming, it generally takes longer than you think to finish something. Furthermore, the earlier you start to work on the project, the more questions you may have for the mentors at the code sprint, and thus the more productive you will be at the code sprint.
  • It's always hard to start the project because students would at first feel overwhelmed by the large existing code base, and do not know where to start. The advice from one of the mentors that really helped me was, instead of stressing over the right place to start, just start somewhere. Try running the application, play around with the code, and you'll naturally become more familiar with the code.
  • The code sprint is a place to meet your team members and mentors, as well as teams from other UCOSP projects. This is your chance to communicate face-to-face with your team, and ask any questions you may have for the mentors. Of course, most of the time is spent on coding, so please bring your laptop! (This may sound like an obvious suggestion, but I didn't really know what the code sprint was about before going there, or whether there would be computers for us to work on. Now that I think about it, everyone is working on different projects, which have different installation requirements, so of course we would need our own laptops if we want to work on our projects! Hahaha...)
Well, that's all from me for now. I really had a great time taking this project course, learning, contributing, and getting to know some very nice people, all at the same time. I hope future UCOSP students will enjoy this precious experience, just as I did! 



Thursday, March 20, 2014

Week11 Blog7

Progress I made
    • This week, most of the time is spent on researching how to play sound using Python/Pyqt4. The methods I've tried include QSound, Phonon, PyGraphics' sound_media.py, pygame, and finally system alert sound.
    1. QSound simply did not play a sound on Ubuntu Linux.
    2. Phonon did play the sound correctly, except that it sits in the event loop and won't exit. So I added some signals code and '''app.connect(media, SIGNAL("finished()"), app, SLOT("quit()"))''' to make it quit after the sound file finished playing. Now the program exited, but gives me a segmentation fault.
    3. PyGraphics' sound_media.py loads and plays sounds well when I try it in the python shell, but if I move the code to a py file, then run it, it did't play a sound.
    4. After attempting to fix the issues above and failing, I tried pygame. Referencing the code snippets from http://stackoverflow.com/questions/7746263/how-play-mp3-with-pygame I got the reminder sound to work! However, asking around on IRC, a mentor informed me that generally we should not store external binary data in source control, and suggested using system notification sounds instead.
    5. So eventually, I switched to using the system alert sound. I found that the code is very simple. There are advantages and drawbacks for this method though. The advantage is that we don't need to store an external sound file. The drawback are, 1: in order for the sound to work, we need to ensure that each laptop doing the recording does not have the system alert sound disabled. 2: the system alert sounds are different across different platforms, so some of them may not sound like alerts, some of the alert sounds may have volumes that are hard to hear, etc.
    • Last week I speculated that the countdown display text may have been set to an absolution position, which is undesirable. However, my investigation into the issue shows that I did indeed use relative position (for example http://zetcode.com/gui/pyqt4/layoutmanagement/).
    • Reset the alignment of the display text to be centred.

    Plans for next week
    • Fully test the auto-recording feature, by designing and implementing more comprehensive test cases.

    Problems
    None.


    Thursday, March 13, 2014

    Week10 Blog6

    Progress I made
    • Researched how to flash the countdown screen and countdown text. Found some code for flashing the text using QPropertyAnimation: https://gist.github.com/justinfx/5318065. But when I tried using this method, it keeps giving me "TypeError: unable to convert a Python 'QBrush' object to a C++ 'QColor' instance". So in the end, I decided to implement it my own way, which is to use another timer to keep track of when to change the colour of the display.
    • Following others' advice, made changes to the display: 1. If there's more than 2 minutes remaining, display only the minutes, e.g. "X min.", otherwise display minutes and seconds, e.g. "01:25"; 2. Flash the screen at 1 minute and at 30 seconds, using inverted screen colours; 3. When there's 10 seconds left, change countdown colour to red.
    • Looked over mentors' code reviews on Github and made some minor changes accordingly

    Plans for next week
    •  I found that the display text size I set for the countdown string shows properly on my computer, but if I show it on a small computer, the proportion isn't right. I need to figure out a way to show the relative position instead of setting an absolute size.
    • Research and implement reminder sound function before the starting the recording of the current talk.

    Problems
    • It seems that I don't understand what "rebase" does in git. On Freeseer's contributor guide, it says "Rebase frequently to incorporate changes from upstream". When I did that, it gave me all the merge conflicts, starting from the first commit I made in my pull request. So after an hour of solving the merge conflicts and pushing the unconflicted version into my Github pull request, I did "rebase" again to make sure I got the latest changes. But this put me right back to where I started: it again showed me all the merge conflicts starting from the first commit... I think I really need to go look up what "rebase" is before doing anything else.

    Thursday, March 6, 2014

    Week9 Blog5

    Progress I made
    • Countdown display now shows the appropriate 00:00:00 when the time is up (the problem from last week)
    • Implemented the stop auto recording cases. Case1: there are no more talks to record and no user interruption, exit the auto-record screen after the last talk. Case2: auto-recording isn't finished, but user decides to end auto record by pressing the "Stop auto-record". Then exit countdown screen and stop recording right away.
    • Disabled all other buttons while in auto recording mode, and returned them to original position after auto recording is done
    • Added message boxes that appear when: 1. no room is selected for auto-recording; 2. there are no upcoming talks to auto-record

    Plans for next week
    • Research how to flash the countdown screen and add reminder sound for reminding the presenter when then auto-record will stop recording 
    • Design the reminder functions so that it the presenter can easily see the countdown and finish the talk before the time runs out
    • Implement the reminder function several times before the end of the recording

    Problems

    None.



     

    Thursday, February 27, 2014

    Week8 Blog4

    Progress I made
    • Changed the countdown display to show in the format hh:mm:ss (AutoRecordWidget.py) 
    • Completed the countdown display. Now both the time until the start of recording and the time remaining until end of recording show up on the screen (record.py)
    • Added code for starting and stopping the auto-recording, in the case where user doesn't manually exit auto-recording (record.py). I spent a veeeeeeery long time debugging this part. The timer for the countdown display and the timer for the wait time before the start of the recording are different. For the wait timer, at first I tried to use QThread's wait(). Then I tried Python time module's sleep(). But this puts the whole Freeseer program to sleep(), including the countdown display. So then I switched to using two QTimer objects, one for waiting until the start of a recording, and the other for waiting until the end of a recording. But somehow the interaction between these two timers messes up the code. So I tried to use just one timer for both countdown. Theoretically it should work, since the two countdowns don't overlap. However, even though I stopped and reset the timer where I think is appropriate, after starting the recording, the timeout signal causes one method to be called repeatedly before the recording stops, thus starting the recording a second time, a third time, a fourth time,..., before it ever stops. In the end, I switched to using QTimer's static function singleShot(). This way, there is no timer instances, and thus no resetting problems. and FINALLY IT WORKED!!! YAY!!! \o/

    Plans for next week
    • Right before the start of recording, countdown shows 00:00:01 instead of 00:00:00. Need to fix it 
    • Make the countdown display more readable: change the font, size, and position of the text and countdown
    • Implement the following cases for stop auto-recording: 
    • case 1: user doesn't manually exit auto-recording, but there are no more talks to record. We need to exit the auto-record screen after the last talk 
    • case 2: auto-recording isn't finished, but user decides to quit by pressing the "Stop auto-record". Then we need to exit and screen and stop recording right away
    • If no talk satisfies the room and time condition for auto-recording in the first place, show message dialog box that informs the user of this
     Problems
    None.


    Wednesday, February 19, 2014

    Week7 Blog3

    Progress I made
    • Fixed last week's blog problem #1, where the auto-record button appeared in the "Record" interface when not necessary
    •  Added method to get talk id from database using current date, time, and room (database.py). This is used for auto-record mode.
    •  Since I have no prior knowledge of PyQt4, I researched about how to use QTime to make a countdown, how to display countdown, as well as how to display messages that change over time. At first, QLCDNumber seems like a nice fit to the countdown I'm trying to implement, since it conveniently displays LCD numbers like a digital clock. However, we also need to display text about the next talk and hint strings like "Time remaining". So in the end, I decided to use a layout instead.  See the bottom of the blog for a list of useful tutorials. 
    • Wrote the beginning of auto_record(), where if you press auto-record, it'll show fullscreen countdown until the next talk starts recording (record.py)  
    • Wrote the widget for display info about talk and time remaining (AutoRecordWidget.py)
    • Added Esc key to exit fullscreen (AutoRecordWidget.py)
    Note: auto-record should record talks starting at or after the current computer time, in the room that is currently displayed in the room field of the recording UI. If there are no talks that qualify this condition, for the code right now, nothing happens.

    Plans for next week
    • Auto mode display: add code for displaying time remaining info during recording (record.py)
    • Recording: add code for start recording and stop recording, while there are still talks to record and we are still in auto mode (record.py)
    • Recording UI: pressing Esc in countdown window will exit fullscreen, not stop the auto-recording. If user clicks the X, then countdown window will close, but not stop recording. At this time, everything in the main recording UI should be disabled except the auto-record button. This button should show "Stop auto-record", and if user clicks on that, then auto-record should stop (record.py)
    • Right now the countdown only shows minutes and seconds. Need to also show the hours (AutoRecordWidget.py)
    Problems
    None.

    Tutorials

    Countdown timer:
    • http://stackoverflow.com/questions/12661211/cant-seem-to-get-pyqt-countdown-timer-to-work
    • http://codeprogress.com/python/libraries/pyqt/showPyQTExample.php?index=396&key=QTimerCountdown
    Useful PyQt4 code snippets, in particular Full Screen
    • http://thewikiblog.appspot.com/wiki/be-productive-with-pyqt4
    Widgets and layouts
    • http://www.pythoncentral.io/pyside-pyqt-tutorial-interactive-widgets-and-layout-containers/
    QSqlQuery
    • http://srinikom.github.io/pyside-docs/PySide/QtSql/QSqlQuery.html#PySide.QtSql.PySide.QtSql.QSqlQuery.value

    Thursday, February 13, 2014

    Week5-6 Blog2

    In this post, I will combine the week just before the code sprint together with this week.

    Progress I made:

    1. Fixed issue #453, where the date in the recording editor displays incorrectly. The problem was in database.py, when we are filtering dates using "Date(time)" instead of just "Date".
    2. In order for automated recording to work, we need to store the start time as well as the end time of a talk. Thus I added the new end time field in the talk editor, report editor, etc., and updated the database to include such a change. As a reminder to myself, here is a list of files I changed:
    • ---framework
      #database.py
      #presentation.py
    • frontend
      ---talkeditor
      #AddTalkWidget.py
      #TalkDetailsWidget.py
      #talkeditor.py
    • --reporteditor
      #ReportEditorWidget.py
      reporteditor.py
    • ---record
      #record.py
      #ReportDialog.py
    3. Updated the already existing unit tests so that they still pass with the newly added end time.
    4. Added the auto-recording button to the main recording interface (with no functionality yet).

    Plans for next week:

    1. Right now the auto-record button not only appears in the "Prepare to record" interface, but also in the "Record" interface. I need to fix it so that it only appears in the main talk editor UI.
    2. Research how to implement full screen as the display screen during auto-recording, and how to display constantly changing messages on screen.
    3. Extract the next talk’s information from the database. Using the starting time and the computer’s current time, display the time until the next talk. Display details about the talk below the time. Repeat this process for every talk until the user presses the exit key, or until there are no more talks to record in the database.
    4. Add a shortcut key that allows the editor to exit from full screen mode.

    Problems:

    1. Currently, rss and csv don't have end time, which means, either the auto-recording feature is not available for rss imports, or when the user tries to use auto-recording, a dialog pops up, asking the user to manually enter the end time.

    Notes:

    The code sprint last weekend was really helpful for me in figuring out the code base, and it was a pleasure to meet all of the mentors and students! I also learned a lot of things from the code sprint. Special thanks to Dennis, who always answered my questions with patience. =)
    Here are some of the things I learned, as a reminder to myself:

    To run Freeseer master branch (the origin):
    1. make sure you committed your changes before proceeding
    2. git checkout master
    3. git pull upstream master
    4. python -m freeseer

    To switch back to your topic branch:
    1. git checkout your-topic-branch

    To split a fix into its own branch and open a new pull request:
    1. git checkout master
    2. git pull upstream master (make sure you are up to date with master branch)
    3. git checkout -b new-topic-branch-name
    4. git log (to see the ID of the commit you want to split)
    5. git cherry-pick commit-ID (e.g.711bd3a4f8f9cb7a28da1522c1d5a6fb304424da)
    6. if it says "fix conflicts", then run git diff
    7. fix the conflicts by deleting the stuff you don't need
    8. git add .
    7. git cherry-pick --continue
    8. to edit the commit message, run git commit --amend
    9. to see what you changed in a particular commit, run git show commmit-ID (the first few characters of the ID is fine, as long as it's unique enough)
    10. make sure those are the commits you want to push
    11. git push origin topic-branch-name

    VERY IMPORTANT:
    Run the unit tests and flake8 before pushing changes up to github! Here is a how-to link:
    https://groups.google.com/forum/#!searchin/freeseer/flake8/freeseer/HdY-IVur0w8/JgPiK6usrSAJ




    Thursday, January 30, 2014

    Week4 Blog1

    This semester, I will be contributing to the Freeseer open source project, as part of the UCOSP program. This will be the start of the weekly blog reports.

    Progress made this week:
    • I kept getting plugin error messages from the terminal, and realized that I needed to install additional libraries httplib, simplejson, and oauth. After installation, the plugin errors disappeared, but for some reason the talk editor can't be opened correctly using "python -m freeseer talk". Also, the displayed fields in the recording UI are not correct
    • After getting help on the IRC, I installed Linux Ubuntu on VMware workstation8, then re-installed the Freeseer dependencies on that virtual machine
    • The talk editor worked fine on Linux, but the recording UI was still not working well. So I opened issues #453 and #454
    • I decided on the issue that I would like to work on, and started writing the project proposal
    • I looked at some of the codes to get a sense of where I would be changing things.
    Plans for next week:
    Problems/blocks:
    • I'm not sure where I should start coding. I only have the general idea that the feature should probably be added somewhere in the /frontend/record files. I think looking at the code in more detail would be helpful in understanding how the whole thing fits together
    • #440 mentions that Freeseer stores metadata about when the presentation starts/ends, but I haven't been able to find the ending time