ralsina / aranduka

Automatically exported from code.google.com/p/aranduka
0 stars 1 forks source link

ODPS publisher fails miserably if the 8080 port is being used #30

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
ODPS publisher plugin listents on localhost:8080 (this is hardcoded). If the 
port is being used, it fails miserably without displaying any error to the user.

1 - The user should be able to configure address and port on the plugin's 
configuration.

2 - The plugin should show a proper error to the user if it can't bind to the 
configured address/port.

Original issue reported on code.google.com by andresgattinoni on 30 Jan 2011 at 4:28

GoogleCodeExporter commented 9 years ago
Replace "ODPS" for "OPDS" :)

Original comment by andresgattinoni on 30 Jan 2011 at 4:32

GoogleCodeExporter commented 9 years ago
It should also show somewhere "You can access your catalog at http://whatever" 

Maybe just start at port 8080 and try raising the number until it works? Por 
numbers are very geeky.

Original comment by roberto.alsina on 30 Jan 2011 at 5:14

GoogleCodeExporter commented 9 years ago
Publishing an OPDS already seems very geeky to me hehe. But if I want another 
person to access my catalog from somewhere outside my machine I should be able 
to tell it to bind to my external address. 

Ideally, it would be better to have a basic and advanced configuration. The 
basic config may say: "Enable access to my catalog from the Internet" and the 
advanced one should let you choose which address and port to bind. If the user 
uses the basic config, we choose the IP from the first network interface and 
try which port works.

Original comment by andresgattinoni on 30 Jan 2011 at 6:36

GoogleCodeExporter commented 9 years ago
Another related thing:

The OPDS plugin currently doesn't have any UI stuff. I don't know if it should.
But, what about having some very basic message handler that based on the 
context can display a QMessageBox, print it to stdout, log it or whatever?

Original comment by andresgattinoni on 30 Jan 2011 at 6:45

GoogleCodeExporter commented 9 years ago
This was actually a user request! A popular ebook reader for mobiles, called 
Stanza, supports OPDS access. So this can be used to transfer books to mobiles.

So does FBReader, but I don' t know how that can be configured (I saw it in 
their sourcecode).

No idea really about the UI, this was just a proof of concept and I don' t know 
if it ever got tested with anything :-)

Original comment by roberto.alsina on 30 Jan 2011 at 7:17

GoogleCodeExporter commented 9 years ago
I remembered I had FBReader installed. But I can't find the option for 
publishing my ebooks (nor its configuration in the preferences dialog).

Original comment by andresgattinoni on 31 Jan 2011 at 2:42

GoogleCodeExporter commented 9 years ago
No, it's backwards, FBReader can access OPDS servers and get the catalogs 
(that's how they access feedbooks)

Original comment by roberto.alsina on 31 Jan 2011 at 3:08

GoogleCodeExporter commented 9 years ago
This issue was updated by revision 69f4fc8049.

First step: added the feature of trying for available ports until it works.
I also added a "get_url" function that should return the URL where the catalog 
is availble, but I'm not sure how to display it and whether it will work 
because of the multi-process stuff.

Original comment by andresgattinoni on 1 Feb 2011 at 3:48

GoogleCodeExporter commented 9 years ago
rfc54447a6f is a little better

Original comment by andresgattinoni on 1 Feb 2011 at 3:53

GoogleCodeExporter commented 9 years ago
This issue was updated by revision fdc36d3db0.

This revision it's yet a little better, removing an unused variable, adding a 
couple of docstrings, and a more precise check of the EADDRINUSE error

Original comment by andresgattinoni on 1 Feb 2011 at 4:02

GoogleCodeExporter commented 9 years ago
Can we use dbus to communicate errors or the URL of the catalog between the 
HTTP server process and the main process of aranduka? And by "can we" I mean 
"how do we" :P

The problem is that currently we don't know the catalog's URL until the server 
is running (and blocking the process).

Original comment by andresgattinoni on 3 Feb 2011 at 1:02

GoogleCodeExporter commented 9 years ago
No we can't use dbus because we want it to work on windows. Use a Queue instead!

Original comment by roberto.alsina on 3 Feb 2011 at 1:06

GoogleCodeExporter commented 9 years ago
I never used it, how would that be? 
Is it possible to have multi-process queues?

Original comment by andresgattinoni on 3 Feb 2011 at 1:20

GoogleCodeExporter commented 9 years ago
Yes, use multiprocessing.Queue:

http://docs.python.org/library/multiprocessing.html#pipes-and-queues

Basically, create a queue from the child process to the parent, and put the 
status there somehow.

On the parent side, use a QTimer to read the queue every once in a while until 
you know what happened to the child.

Original comment by roberto.alsina on 3 Feb 2011 at 1:40

GoogleCodeExporter commented 9 years ago
Mmmm I can't even get the timer working :P
Here's part of the code:

    def check_url (self):
        print "Checking URL..."
        publisher = __import__('publisher')
        try:
            url = publisher.queue.get_no_wait()
            QtGui.QMessageBox.information(self, \
                                      u'Catalog being published', \
                                      u'You can access your catalog on: %s'%url)
        except Queue.Empty:
            pass

    def publish(self):        
        if not self._proc:
            dirname = os.path.join(
                os.path.abspath(
                    os.path.dirname(__file__)))
            sys.path.append(dirname)

            print "Setting up timer..."
            timer = QtCore.QTimer()
            print timer
            QtCore.QObject.connect(timer, QtCore.SIGNAL('timeout()'), self.check_url)
            print "Starting timer"
            timer.start(1000)

            publisher = __import__('publisher')
            self._proc = multiprocessing.Process(target = publisher.real_publish)
            self._proc.daemon = True
            self._proc.start()

check_url is never called. What am I doing wrong?

Original comment by andresgattinoni on 3 Feb 2011 at 2:17

GoogleCodeExporter commented 9 years ago
probably timer is getting deleted because you are not saving a reference.

use self.timer or similar.

Original comment by roberto.alsina on 3 Feb 2011 at 2:50

GoogleCodeExporter commented 9 years ago
Also:

timer.timeout.connect(self.check_url) is soooo much nicer ;-)

Sure, we FORCE people to use a PyQt less than two years old, but let's go crazy 
here ;-)

Original comment by roberto.alsina on 3 Feb 2011 at 2:51

GoogleCodeExporter commented 9 years ago
Ok, that worked. The problem now is that I don't know the correct URL until the 
HTTP server is running... and then I'm blocked... I could try to open a socket 
*manually*, but, do you have a better solution?

I tried this, but it doesn't work:

        _host, _port = get_bind_address()
        for n in xrange(1,1024):
            try:
                url = "http://%s:%d"%(_host, _port)
                print "Appending URL to queue: %s"%url
                queue.put(url)
                run(host=_host, port=_port)
                break
            except socket.error, e:
                queue.empty()
                code, string = e
                if code == errno.EADDRINUSE:
                    # If the port is in use, try another one        
                    _port += 1
                else:
                    raise e

Original comment by andresgattinoni on 3 Feb 2011 at 3:08

GoogleCodeExporter commented 9 years ago
I guess you will have to patch bottle.run

http://code.google.com/p/aranduka/source/browse/src/bottle.py?r=integrate#1381

Original comment by roberto.alsina on 3 Feb 2011 at 10:34

GoogleCodeExporter commented 9 years ago
Looking at the code maybe I can fix it by instantiating the WSGIRefServer (for 
checking the port) in the publisher and then passing it to bottle.run. 

Original comment by andresgattinoni on 3 Feb 2011 at 12:52

GoogleCodeExporter commented 9 years ago
Sure!

Original comment by roberto.alsina on 3 Feb 2011 at 2:29

GoogleCodeExporter commented 9 years ago

Original comment by andresgattinoni on 4 Feb 2011 at 2:02

GoogleCodeExporter commented 9 years ago
This issue was updated by revision 44d4e8ff6e.

In the end it was easier to use a good old socket to check for host/port 
availability than hacking bottle.
The issue is fixed now. Can you review it?

New issue
Summary: Add posibility to stop the OPDS catalog server
Labels: Type-Enhancement Priority-Medium
We should add the posibility of stopping the OPDS catalog server without the 
need closing Aranduka.
One possibility would be to change the menu's action from "Publish catalog" to 
"Stop catalog server" or something like that.
But that raises the issue of how to implement that within the plugin structure.

Original comment by andresgattinoni on 4 Feb 2011 at 2:23

GoogleCodeExporter commented 9 years ago
It seems that you can't update an issue and create a new one from the same 
commit :P

Original comment by andresgattinoni on 4 Feb 2011 at 2:24

GoogleCodeExporter commented 9 years ago
This issue was closed by revision 5f3a66c99d.

Original comment by andresgattinoni on 6 Feb 2011 at 7:43