# Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: sami.saada@gmail.com-20100502212517-ijwc7hiv9t1axyr3 # target_branch: bzr+ssh://bazaar.launchpad.net/~openfilepad-\ # maintainers/qfriendslol/main/ # testament_sha1: a39d35ed2d8ad40a1992dd6e617e9d03b74ed1f3 # timestamp: 2010-05-03 00:25:49 +0300 # base_revision_id: toni.ruottu@iki.fi-20100502105559-rjzhecfb0ljlm51j # # Begin patch === modified file 'COPYING' --- COPYING 2009-10-18 21:45:19 +0000 +++ COPYING 2010-05-02 15:53:52 +0000 @@ -1,8 +1,8 @@ CC0, http://creativecommons.org/publicdomain/zero/1.0/ -To the extent possible under law, QFriendsLOL waivers have waived all copyright and related or neighboring rights to QFriendsLOL. This work is published from various places. +To the extent possible under law, OpenFilepad waivers have waived all copyright and related or neighboring rights to OpenFilepad. This work is published from various places. -QFriendsLOL waivers: +OpenFilepad waivers: Toni Ruottu , Finland 2009 Martti Rannanjärvi , Finland 2009 Sami Saada , Finland 2009 === modified file 'README' --- README 2009-11-04 23:59:10 +0000 +++ README 2010-05-02 15:53:52 +0000 @@ -1,28 +1,28 @@ - QQQ FFFF RRRR III EEEE N N DDD SSSS L OOO L - Q Q F R R I E NN N D D S L O O L - Q Q FFFF RRRR I EE N N N D D SSS L O O L - Q Q F R R I E N NN D D S L O O L - QQQ Q F R R III EEEE N N DDD SSSS LLLL OOO LLLL - - - QFriendsLOL is a simple QT file drop box application that enables friends + OOO PPP EEEE N N FFFF I L EEEE PPP A DDD + O O P P E NN N F I L E P P A A D D + O O PPP EE N N N FFFF I L EE PPP AAAAA D D + O O P E N NN F I L E P A A D D + OOO P EEEE N N F I LLLL EEEE P A A DDD + + + OpenFilepad is a simple QT file drop box application that enables friends to exchange files by using OpenLookup v2. To extract and run the latest - QFriendsLOL source release in Ubuntu 9.10 Karmic Koala, I'd do the + OpenFilepad source release in Ubuntu 9.10 Karmic Koala, I'd do the following... sudo apt-get install python-crypto python-simplejson python-qt4 subversion -tar xpzf qfriendslol-0.1.2.tar.gz -cd qfriendslol-0.1.2/src +tar xpzf openfilepad-0.2.1.tar.gz +cd openfilepad-0.2.1/src svn checkout http://openlookup.googlecode.com/svn/v2/openlookup -./qfriendslol.pyw +./openfilepad.pyw Users of other Linux-based systems are hopefully able to adopt these instructions to their needs. There is a theoretical possibility that - QFriendsLOL might work on Windows or Mac OS X. In the software's + OpenFilepad might work on Windows or Mac OS X. In the software's current state we do not recommend using it in such foreign environments. - best regards, QFriendsLOL developers + best regards, OpenFilepad developers === modified file 'doc/manual.tex' --- doc/manual.tex 2009-11-20 15:39:08 +0000 +++ doc/manual.tex 2010-05-02 15:53:52 +0000 @@ -7,7 +7,7 @@ \usepackage{graphicx} \usepackage{amssymb, amsmath} \usepackage{lmodern} -\title{\Huge{QFriendsLOL 0.2.1} +\title{\Huge{OpenFilepad 0.2.1} \\\normalsize{User Manual}} %\date{\today} %\author{Martti Rannanjärvi , @@ -19,33 +19,33 @@ \section*{Introduction} %What your program's purpose is, who it is for max 1 page. -QFriendsLOL\footnote{https://launchpad.net/qfriendslol/} is an application with which one can publish files on the Internet without acquiring a web space. For this, QFriendsLOL uses a federated datastore called OpenLookup \footnote{http://openlookup.net/} V2. Openlookup allows anyone to store arbitrary data items for a short time without requiring registration. With QFriendsLOL one can give the intended recipients one's QFriendsLOL nickname or userid with which they can find all the files one has published. The nickname is an easily memorable handle, the userid is a unique identifier. - -People who can already publish files in a web space may also benefit from using QFriendsLOL. While a web space can become bloated and unwieldy over time, a QFriendsLOL repository remains easily clean. The data published in QFriendsLOL is kept online for one week, and becomes inaccessible after that. If a user is inactive for one week, all their data, and data of them, is cleared from the datastore. When one returns to QFriendsLOL after being forgotten, one's avatar and nickname are automatically reannounced. - -This document describes the features and limitation of QFriendsLOL, describes how to use it, and presents some selected implementation details. +OpenFilepad\footnote{https://launchpad.net/qfriendslol/} is an application with which one can publish files on the Internet without acquiring a web space. For this, OpenFilepad uses a federated datastore called OpenLookup \footnote{http://openlookup.net/} V2. Openlookup allows anyone to store arbitrary data items for a short time without requiring registration. With OpenFilepad one can give the intended recipients one's OpenFilepad nickname or userid with which they can find all the files one has published. The nickname is an easily memorable handle, the userid is a unique identifier. + +People who can already publish files in a web space may also benefit from using OpenFilepad. While a web space can become bloated and unwieldy over time, a OpenFilepad repository remains easily clean. The data published in OpenFilepad is kept online for one week, and becomes inaccessible after that. If a user is inactive for one week, all their data, and data of them, is cleared from the datastore. When one returns to OpenFilepad after being forgotten, one's avatar and nickname are automatically reannounced. + +This document describes the features and limitation of OpenFilepad, describes how to use it, and presents some selected implementation details. \section*{Features and Limitations} %Which features are available, which bugs and limitations are known) max 1 page. This section presents some of the application's features and limitations. First we go through some details related to uploading, downloading, and deleting files. Then we discuss some limitations related to users' avatar images. Finally we consider suitability for porting the application to other platforms. -A user can have maximum of 30 files available simultaneously in QFriendsLOL. Filenames of the shared files are not allowed to be longer than 256 characters. The files uploaded with QFriendsLOL are protected against forgery. It should be impossible for a QFriendsLOL user to publish files with the userid of another user. Users announce a nickname enabling other people to find them. They can also upload an avatar to help their friends to identify them. An avatar or a nickname can be forged. Whenever protection from forgery is desired, one has to verify the identity of a user by exchanging userids trough a protected channel. +A user can have maximum of 30 files available simultaneously in OpenFilepad. Filenames of the shared files are not allowed to be longer than 256 characters. The files uploaded with OpenFilepad are protected against forgery. It should be impossible for a OpenFilepad user to publish files with the userid of another user. Users announce a nickname enabling other people to find them. They can also upload an avatar to help their friends to identify them. An avatar or a nickname can be forged. Whenever protection from forgery is desired, one has to verify the identity of a user by exchanging userids trough a protected channel. -The group who can download your files cannot be restricted in any way. Anyone who knows someone's QFriendsLOL nickname can download their files. It is also possible to write a piece of software that retrieves all files of all users using QFriendsLOL. +The group who can download your files cannot be restricted in any way. Anyone who knows someone's OpenFilepad nickname can download their files. It is also possible to write a piece of software that retrieves all files of all users using OpenFilepad. Deleting files does not actually remove the files from the datastore. They are only removed from the file listing, and only disappear from the data store when their time to live runs out. Files are listed as available to download for six days and after that some parts of the file may still be accessible in the data store for a day or so. This window gives ongoing downloads a chance to finish, when the time runs out during a download. After seven days the data store stops giving out the data, but copies of the file may remain on the servers for arbitrary amounts of time. -The avatar file size is limited to 99999 bytes. This prevents evil hackers or broken implementations from jamming the user interfaces. Currently the application does not help users to make their images smaller, and in fact it doesn't even check the file type. An image file may or may not work based on some internal magic of the image rendering library that we use. A user can also set their avatar to an image which is larger than the limit. The image will still be uploaded to the datastore, but the client will refuse to download it. We hope we can improve the handling of avatars in future versions of QFriendsLOL. +The avatar file size is limited to 99999 bytes. This prevents evil hackers or broken implementations from jamming the user interfaces. Currently the application does not help users to make their images smaller, and in fact it doesn't even check the file type. An image file may or may not work based on some internal magic of the image rendering library that we use. A user can also set their avatar to an image which is larger than the limit. The image will still be uploaded to the datastore, but the client will refuse to download it. We hope we can improve the handling of avatars in future versions of OpenFilepad. -QFriendsLOL is not cross-platform yet. It has only been tested on Ubuntu and Gentoo. Currently, the application does not allow you to choose a download directory, but the files are downloaded to ~/.Desktop directory. We have discussed improving this in the future versions of the application. QFriendsLOL should be easily portable to platforms supported by QT and Python. Platforms targeted for future versions include systems ranging from Max OS X and Windows to Maemo and Haiku. While a range of platforms seems plausible, running QFriendsLOL currently requires a writable filesystem, as avatar pictures and list of friends are stored in the local filesystem. +OpenFilepad is not cross-platform yet. It has only been tested on Ubuntu and Gentoo. Currently, the application does not allow you to choose a download directory, but the files are downloaded to ~/.Desktop directory. We have discussed improving this in the future versions of the application. OpenFilepad should be easily portable to platforms supported by QT and Python. Platforms targeted for future versions include systems ranging from Max OS X and Windows to Maemo and Haiku. While a range of platforms seems plausible, running OpenFilepad currently requires a writable filesystem, as avatar pictures and list of friends are stored in the local filesystem. \section*{User Guide} %Explain functions of the program in a straightforward, step-by-step manner, so that average users can understand them. Keep in mind the target audience that you mention in Intro. Have at least one use-case. -This section will teach you how to get most out of your fresh QFriendsLOL installation. The next chapter will give you an overall idea of how the application works. Then we'll revisit each view in detail to have you backed up in case you get lost on your way. Finally we present an example usage scenario to give you an idea how the application might be used. +This section will teach you how to get most out of your fresh OpenFilepad installation. The next chapter will give you an overall idea of how the application works. Then we'll revisit each view in detail to have you backed up in case you get lost on your way. Finally we present an example usage scenario to give you an idea how the application might be used. -QFriendsLOL has a tab based user interface. Each tab in the user interface represents a person. The local user (that is you) has a special home tab. It is special in that it can never be removed. It allows you to upload files to the system, and remove files from it. Home tab is the leftmost tab. It is identified by a small house icon on the tab header. In addition to the home tab QFriendsLOL provides a tab with plus sign (+) in the tab header. You can turn this tab into the tab of one of your friends. Just find him by nickname or userid, and click add. Adding a user will also create a new + tab, allowing you to add another friend. Initially you'll only have your home tab and one + tab to get you started. +OpenFilepad has a tab based user interface. Each tab in the user interface represents a person. The local user (that is you) has a special home tab. It is special in that it can never be removed. It allows you to upload files to the system, and remove files from it. Home tab is the leftmost tab. It is identified by a small house icon on the tab header. In addition to the home tab OpenFilepad provides a tab with plus sign (+) in the tab header. You can turn this tab into the tab of one of your friends. Just find him by nickname or userid, and click add. Adding a user will also create a new + tab, allowing you to add another friend. Initially you'll only have your home tab and one + tab to get you started. \clearpage \begin{figure}[h] @@ -68,7 +68,7 @@ \end{center} \end{figure} -The friend finder view has a friend finder which allows you to find your friends who have been using QFriendsLOL within a week. See Figure \ref{friendfinder} for an example of a friend finder view. You can do so by typing either your friend's nickname or userid to the text field and clicking the find button. Only exact matches will work. The application does not support partial matching on nicknames. If your search for a nickname gives multiple matches, images and userids of the resulting users are shown to allow you to infer which of them is the desired one. Note that userids cannot be faked, so you can always use them to correctly identify a user. Each user in the listing has an add button. Clicking on the button will choose that user to be added to your friend tabs, and a new friend addition tab to be created. When you search for people you have already added as your friend, QFriendsLOL will present you a show button instead of an add button. Clicking on the show button will take you to your friend's tab, and clears the results in your friend finder. +The friend finder view has a friend finder which allows you to find your friends who have been using OpenFilepad within a week. See Figure \ref{friendfinder} for an example of a friend finder view. You can do so by typing either your friend's nickname or userid to the text field and clicking the find button. Only exact matches will work. The application does not support partial matching on nicknames. If your search for a nickname gives multiple matches, images and userids of the resulting users are shown to allow you to infer which of them is the desired one. Note that userids cannot be faked, so you can always use them to correctly identify a user. Each user in the listing has an add button. Clicking on the button will choose that user to be added to your friend tabs, and a new friend addition tab to be created. When you search for people you have already added as your friend, OpenFilepad will present you a show button instead of an add button. Clicking on the show button will take you to your friend's tab, and clears the results in your friend finder. \begin{figure}[h] \begin{center} @@ -78,20 +78,20 @@ \end{center} \end{figure} -All the friends that you have added to QFriendsLOL have their own tab. The friend view available to you in such a tab has some resemblance to your home tab. See Figure \ref{friendview} for an example of a friend view. The main difference is that you only have read access to your friends view. You cannot change their nickname or avatar picture. You can neither delete files, nor upload new files. New files can only be uploaded trough your home view. You can remove a friend's tab from QFriendsLOL by clicking on the forget button beside your friends personal information. +All the friends that you have added to OpenFilepad have their own tab. The friend view available to you in such a tab has some resemblance to your home tab. See Figure \ref{friendview} for an example of a friend view. The main difference is that you only have read access to your friends view. You cannot change their nickname or avatar picture. You can neither delete files, nor upload new files. New files can only be uploaded trough your home view. You can remove a friend's tab from OpenFilepad by clicking on the forget button beside your friends personal information. -As an example use case we will now consider Jane and Tarzan chatting on the internet about their jungle adventure. Jane is digitizing her diary of the jungle adventure and wishes Tarzan would review her writing. She saves her writing as jungletale.odt. Jane opens QFriendsLOL and clicks upload from the home tab. QFriendsLOL asks her to pick a file. She browses her computer's filesystem, selects jungletale.odt and clicks OK. The upload starts, and lasts for a few seconds. Jane tells Tarzan her QFriendsLOL nickname, Jane76, and the name of the uploaded file. Tarzan installs QFriendsLOL and clicks on the plus sign, opening the tab used for adding new users. He makes QFriendsLOL show him users named Jane76. The query returns multiple results and one of the users looks like Jane. Tarzan confirms the cryptographically protected userid to be Jane's and clicks the add button of the corresponding search result, adding Jane to his friends. Tarzan sees Jane's profile in a freshly appearing tab which contains a file listing where Tarzan finds jungletale.odt. He selects it and clicks download. After a few seconds the file appears on his Desktop. Tarzan opens the document in a word processor to make sure he got the right file. The file seems to be what Jane suggested it would be. In the chat window, Tarzan tells Jane that he will read the story after feeding the monkeys. +As an example use case we will now consider Jane and Tarzan chatting on the internet about their jungle adventure. Jane is digitizing her diary of the jungle adventure and wishes Tarzan would review her writing. She saves her writing as jungletale.odt. Jane opens OpenFilepad and clicks upload from the home tab. OpenFilepad asks her to pick a file. She browses her computer's filesystem, selects jungletale.odt and clicks OK. The upload starts, and lasts for a few seconds. Jane tells Tarzan her OpenFilepad nickname, Jane76, and the name of the uploaded file. Tarzan installs OpenFilepad and clicks on the plus sign, opening the tab used for adding new users. He makes OpenFilepad show him users named Jane76. The query returns multiple results and one of the users looks like Jane. Tarzan confirms the cryptographically protected userid to be Jane's and clicks the add button of the corresponding search result, adding Jane to his friends. Tarzan sees Jane's profile in a freshly appearing tab which contains a file listing where Tarzan finds jungletale.odt. He selects it and clicks download. After a few seconds the file appears on his Desktop. Tarzan opens the document in a word processor to make sure he got the right file. The file seems to be what Jane suggested it would be. In the chat window, Tarzan tells Jane that he will read the story after feeding the monkeys. \section*{Implementation Highlights} %What is special about your implementation of this program? What kind of innovative solutions you have applied in its development? -QFriendsLOL uses a freely accessible datastore called OpenLookup. In this section we will discuss some characteristics of OpenLookup. In next paragraph we'll discuss time limits. Then we will continue to by discussing size limits and integrity checking. Finally we explain how OpenLookup attempts to protect datastore administrators from the data they may end up storing. +OpenFilepad uses a freely accessible datastore called OpenLookup. In this section we will discuss some characteristics of OpenLookup. In next paragraph we'll discuss time limits. Then we will continue to by discussing size limits and integrity checking. Finally we explain how OpenLookup attempts to protect datastore administrators from the data they may end up storing. Information stored in the datastore is accessible for one week after uploading. During a high load parts of a file may disappear from the network earlier. This is not desirable, but should not happen too often during normal operation. It would be possible to refreshed the data from local disk occasionally, but the expiration seems to be a useful feature. It cleans up the system and clarifies its temporal nature. When all files have a short time to live it is guaranteed that no-one will use the system for system backups. Data is stored in OpenLookup as small signed blocks. Data items have a size limit of 8192 bytes. Our application splits files into multiple blocks that are stored separately. Each item is signed by it's publisher with public key cryptography, to prevent against forgery. The server checks integrity and authenticity of each item upon arrival. -Each item is referred to with an arbitrary string label $l$. Only hash $h(l)$ of the label is revealed to the storage servers. Thus storage servers do not learn the plain text labels used for referring the items. Each plaintext item $i$ is encrypted with symmetric encryption using the plain text label as a key to produce an encrypted item $E_li$. This is supposed to give the data store maintainers some protection against responsibilities related to the information stored in the datastore. A datastore maintainer could use a brute force guessing attack, or study data model of QFriendsLOL to break this protection. This should however not matter to us, as the encryption is used in first place to protect the administrator and not to protect the customer. +Each item is referred to with an arbitrary string label $l$. Only hash $h(l)$ of the label is revealed to the storage servers. Thus storage servers do not learn the plain text labels used for referring the items. Each plaintext item $i$ is encrypted with symmetric encryption using the plain text label as a key to produce an encrypted item $E_li$. This is supposed to give the data store maintainers some protection against responsibilities related to the information stored in the datastore. A datastore maintainer could use a brute force guessing attack, or study data model of OpenFilepad to break this protection. This should however not matter to us, as the encryption is used in first place to protect the administrator and not to protect the customer. \end{document} === modified file 'release.sh' --- release.sh 2009-11-20 16:49:27 +0000 +++ release.sh 2010-05-02 15:53:52 +0000 @@ -1,20 +1,21 @@ #!/bin/sh # -# QFriendsLOL - release.sh +# OpenFilepad - release.sh # # Authors: Toni Ruottu , Finland +# Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. -VERSION=0.1.2 -RELEASE=qfriendslol-$VERSION +VERSION=0.2.1 +RELEASE=openfilepad-$VERSION mkdir -p release bzr export release/$RELEASE === modified file 'src/filelist.py' --- src/filelist.py 2009-11-20 16:49:27 +0000 +++ src/filelist.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - filelist.py +# OpenFilepad - filelist.py # -# Authors: Sami Saada , Finland +# Authors: Martti Rannanjärvi , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. import gui.logic === modified file 'src/gui/fileop.py' --- src/gui/fileop.py 2009-11-20 16:49:27 +0000 +++ src/gui/fileop.py 2010-05-02 15:53:52 +0000 @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - fileop.py +# OpenFilepad - fileop.py # # Authors: Toni Ruottu , Finland # Martti Rannanjärvi , Finland @@ -9,9 +9,9 @@ # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. === modified file 'src/gui/friendtab.py' --- src/gui/friendtab.py 2009-11-20 16:49:27 +0000 +++ src/gui/friendtab.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - friendtab.py +# OpenFilepad - friendtab.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. === modified file 'src/gui/hometab.py' --- src/gui/hometab.py 2009-11-20 16:49:27 +0000 +++ src/gui/hometab.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - hometab.py +# OpenFilepad - hometab.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. === modified file 'src/gui/logic.py' --- src/gui/logic.py 2009-11-20 16:49:27 +0000 +++ src/gui/logic.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - logic.py +# OpenFilepad - logic.py # # Authors: Martti Rannanjärvi , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. def seconds2string(s): === modified file 'src/gui/mainwindow.py' --- src/gui/mainwindow.py 2009-11-20 16:49:27 +0000 +++ src/gui/mainwindow.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - mainwindow.py +# OpenFilepad - mainwindow.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. from usertabwidget import UserTabWidget @@ -22,7 +22,7 @@ def __init__(self, control, *args): apply(QMainWindow.__init__, (self, ) + args) - self.setWindowTitle(u'QFriendsLOL') + self.setWindowTitle(u'OpenFilepad') self._control = control self.setWindowIcon(QIcon(self._control.getGFXPath() + '/logo.svg')) self._userTabs = UserTabWidget(control) === modified file 'src/gui/newfriendtab.py' --- src/gui/newfriendtab.py 2009-11-20 16:49:27 +0000 +++ src/gui/newfriendtab.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - newfriendtab.py +# OpenFilepad - newfriendtab.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. === modified file 'src/gui/userfiles.py' --- src/gui/userfiles.py 2009-11-20 16:49:27 +0000 +++ src/gui/userfiles.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - userfiles.py +# OpenFilepad - userfiles.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. from PyQt4.QtGui import QWidget === modified file 'src/gui/userinfo.py' --- src/gui/userinfo.py 2010-05-02 09:12:25 +0000 +++ src/gui/userinfo.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - userinfo.py +# OpenFilepad - userinfo.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. === modified file 'src/gui/userpicture.py' --- src/gui/userpicture.py 2009-11-20 16:49:27 +0000 +++ src/gui/userpicture.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - userpicture.py +# OpenFilepad - userpicture.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. from PyQt4.QtGui import QHBoxLayout === modified file 'src/gui/usertab.py' --- src/gui/usertab.py 2009-11-20 16:49:27 +0000 +++ src/gui/usertab.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - usertab.py +# OpenFilepad - usertab.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. from PyQt4.QtGui import QWidget === modified file 'src/gui/usertabwidget.py' --- src/gui/usertabwidget.py 2009-11-20 16:49:27 +0000 +++ src/gui/usertabwidget.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - usertabwidget.py +# OpenFilepad - usertabwidget.py # # Authors: Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. from hometab import HomeTab === modified file 'src/guicontrol.py' --- src/guicontrol.py 2009-11-20 16:49:27 +0000 +++ src/guicontrol.py 2010-05-02 21:25:17 +0000 @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - guicontrol.py +# OpenFilepad - guicontrol.py # # Authors: Toni Ruottu , Finland # Sami Saada , Finland @@ -9,9 +9,9 @@ # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. from remote import Remote, NICKNAME_LENGTH_MAX @@ -32,7 +32,7 @@ if not os.environ.has_key('HOME'): os.environ['HOME'] = os.path.join(os.environ['HOMEDRIVE'], \ os.environ['HOMEPATH']) - self._store = Store(Realfs([os.environ['HOME'], '.qfriendslol'])) + self._store = Store(Realfs([os.environ['HOME'], '.openfilepad'])) self._remote = Remote() self._tabW = None self._tabs = [] @@ -64,7 +64,7 @@ if not mugshot == self.getStore().getMugshot(): self.getStore().putMugshot(mugshot) pngfile = StringIO.StringIO(mugshot) - u = r.upload(pngfile, 'mugshot.png', len(mugshot)) + u = self.getRemote().upload(pngfile, 'mugshot.png', len(mugshot)) while u.ready < u.blocks: u.next() @@ -85,8 +85,8 @@ def getMugshot(self, uid): pngfile = StringIO.StringIO() - d = r.download(pngfile, 'mugshot.png', uid) - if d.size <= 99999: + d = self.getRemote().download(pngfile, 'mugshot.png', uid) + if d.filesize <= 99999: while d.ready < d.blocks: d.next() return pngfile.getvalue() === added file 'src/openfilepad.pyw' --- src/openfilepad.pyw 1970-01-01 00:00:00 +0000 +++ src/openfilepad.pyw 2010-05-02 15:53:52 +0000 @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# OpenFilepad - openfilepad.pyw +# +# Authors: Sami Saada , Finland +# + +# CC0, http://creativecommons.org/publicdomain/zero/1.0/ +# +# To the extent possible under law, OpenFilepad waivers +# have waived all copyright and related or neighboring +# rights to OpenFilepad. This work is published from +# various places. + +from guicontrol import GUIControl +from gui.mainwindow import MainWindow + +import signal +import sys +import os.path +from PyQt4.QtGui import QApplication + +def main(): + signal.signal(signal.SIGINT, signal.SIG_DFL) + app = QApplication(sys.argv) + + control = GUIControl() + control.setGFXPath(os.path.dirname(__file__) + '/gfx') + + # Republish user identity. + control.republish() + + window = MainWindow(control) + window.show() + + app.exec_() + +if __name__ == '__main__': + main() === removed file 'src/qfriendslol.pyw' --- src/qfriendslol.pyw 2009-11-20 16:49:27 +0000 +++ src/qfriendslol.pyw 1970-01-01 00:00:00 +0000 @@ -1,41 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# -# QFriendsLOL - qfriendslol.pyw -# -# Authors: Sami Saada , Finland -# - -# CC0, http://creativecommons.org/publicdomain/zero/1.0/ -# -# To the extent possible under law, QFriendsLOL waivers -# have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from -# various places. - -from guicontrol import GUIControl -from gui.mainwindow import MainWindow - -import signal -import sys -import os.path -from PyQt4.QtGui import QApplication - -def main(): - signal.signal(signal.SIGINT, signal.SIG_DFL) - app = QApplication(sys.argv) - - control = GUIControl() - control.setGFXPath(os.path.dirname(__file__) + '/gfx') - - # Republish user identity. - control.republish() - - window = MainWindow(control) - window.show() - - app.exec_() - -if __name__ == '__main__': - main() === modified file 'src/realfs.py' --- src/realfs.py 2009-11-20 16:49:27 +0000 +++ src/realfs.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,17 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - realfs.py +# OpenFilepad - realfs.py # # Authors: Martti Rannanjärvi , Finland +# Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. import os @@ -61,7 +62,7 @@ def tests(): ''' - >>> fs = Realfs([os.environ['HOME'], '.qfriendslol']) + >>> fs = Realfs([os.environ['HOME'], '.openfilepad']) >>> fs.mkdir([]) >>> fs.ls([]) [] === modified file 'src/remote.py' --- src/remote.py 2009-11-20 16:49:27 +0000 +++ src/remote.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,17 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - remote.py +# OpenFilepad - remote.py # # Authors: Toni Ruottu , Finland +# Sami Saada , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. from openlookup.client.singleton import Proxy @@ -19,7 +20,7 @@ import simplejson as json import time -APP_T = u'qfriendslol' +APP_T = u'openfilepad' ADVERT_T = APP_T+u'-advertise-%s' # joe -> '' NICK_T = APP_T+u'-nickname.json' # -> '"joe"' FILES_T = APP_T+u'-files.json' # -> '["foo.txt", "bar.png"]' === modified file 'src/store.py' --- src/store.py 2009-11-20 16:49:27 +0000 +++ src/store.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - store.py +# OpenFilepad - store.py # # Authors: Martti Rannanjärvi , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. class Store(object): === modified file 'src/virtualfs.py' --- src/virtualfs.py 2009-11-20 16:49:27 +0000 +++ src/virtualfs.py 2010-05-02 15:53:52 +0000 @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- # -# QFriendsLOL - virtualfs.py +# OpenFilepad - virtualfs.py # # Authors: Martti Rannanjärvi , Finland # # CC0, http://creativecommons.org/publicdomain/zero/1.0/ # -# To the extent possible under law, QFriendsLOL waivers +# To the extent possible under law, OpenFilepad waivers # have waived all copyright and related or neighboring -# rights to QFriendsLOL. This work is published from +# rights to OpenFilepad. This work is published from # various places. class Virtualfs(object): # Begin bundle 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